动态规划2018-08-05

  今天讲了DP(dynamic programming),不同与贪心,贪心只顾及了当前的最优解,而没有顾及到全局,往往会WA某些点,而DP是考虑全局,把所有状态都考虑到了。
  DP分为状态,决策三部分,阶段是指DP的层次,而状态是指当前的各个变量,决策就是指最优的策略。
  题目(自编):逃离恶魔塔
  题目描述:小A有m滴血,现在他要逃离恶魔塔(呈三角形),已知第i层有i个关卡,每个关卡都有一个怪兽,有x滴血,小A到达这里时会扣x滴血。小A想知道他能否成功逃离恶魔塔,如果无法逃离,输出"Orz",否则,输出小A所留血量。
  输入样例:
  第一行输入n和m,分别表示恶魔塔的层数以及小A的血量。
  接下来n行,每行输入i个整数,分别表怪物的血量。
  输出样例:
  如果小A无法逃离恶魔塔,输出"Orz",否则,输出小A剩余血量。
  样例:
  1.
  3 20
  22
  4 2
  5 1 12
  Orz
  2.
  3 20
  2
  4 2
  5 1 12
  15

思路:这道题是一道简单DP,从下往上递推,可以得出转移方程:f[i][j]=min(f[i+1][j],f[i+1][j+1])+a[i][j]
附上代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=100+5;
int a[maxn][maxn],f[maxn][maxn];
int main(){
    int n,m,i,j,k;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
            cin>>a[i][j];
    for(int i=n;i>=1;i--)
        for(int j=1;j<=i;j++)
            f[i][j]=min(f[i+1][j],f[i+1][j]+1)+a[i][j];
    if(m<=f[1][1])
       cout<<"Orz"<<endl;
    else
       cout<<m-f[1][1]<<endl;
    return 0;
}

还有一道题:https://www.luogu.org/problemnew/show/P1002
这道题也可以用DP来做,得出转移方程l[i][j]=l[i-1][j]+l[i][j-1];
附上代码:

#include <iostream>
#include <cstdio>
long long a,b,n,m,l[22][22],map[23][23];
using namespace std;
int main()
{
    cin>>n>>m>>a>>b;
    map[a][b]=1;
    map[a-1][b-2]=1;
    map[a-2][b-1]=1;
    map[a-2][b+1]=1;
    map[a-1][b+2]=1;
    map[a+1][b-2]=1;
    map[a+2][b-1]=1;
    map[a+2][b+1]=1;
    map[a+1][b+2]=1;    
    l[1][0]=1;
    for(int i=1;i<=n+1;++i)
        for(int j=1;j<=m+1;++j)
          { 
            l[i][j]=l[i-1][j]+l[i][j-1];
            if(map[i-1][j-1]) 
               l[i][j]=0;
          }
    cout<<l[n+1][m+1];
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42875611/article/details/81434961
今日推荐