基础DP-poj2385-数塔DP变形-挑战程序设计2

来源:互联网 发布:乾隆红楼梦 知乎 编辑:程序博客网 时间:2024/05/16 15:27

突然发现这道题就是一道数塔dp的变形。
有些dp的模型是dag 有向无环图
这种题的思路就是数塔。
每一层都有不同的变化,并且答案之间有很强的结构。推出规律比计算要强太多了,暴力多少是个头啊。
思路:
状态转移方程
dp[n][i]=max(dp[n-1][i-1],dp[n-1][i]);
并且还要判断当前是否命中。
数据 假设为 1 2 1 2,最多移动三次
第一层是当1秒时,转移多少次的分数。即为
1 0 1.
为2秒时,转移的分数,即为
1 1 1,再加上现在的,为
1 2 1。
代码如下。

#include <iostream>#include <cstdio>#include <cmath>/*这道题很早就写过了,知道是dp,但是连状态方程都没想到。。但是当时没有完全弄明白过程。其实是一个dp的过程,更确切的是,类似数塔dp。对当前结果的保存,更类似于对a的相加。*/using namespace std;const int maxn=1200;const int maxm=200;int main(){   int m,n;    int dp[maxn][maxm];    int a[maxn];    scanf("%d%d",&m,&n);    for(int i=1;i<=m;i++)    {   scanf("%d",&a[i]);    }    for(int i=1;i<=m;i++)    {   for(int j=0;j<=n;j++)         {   if(j==0)             dp[i][j]=dp[i-1][j]+a[i]%2;//当在1处时,就是没动,会碰到这个苹果。             dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]);             if(a[i]==j%2+1)             {  dp[i][j]++;             }         }    }    int big=-0x3f3f3f3f;    for(int i=0;i<=n;i++)    {   if(dp[m][i]>big)        big=dp[m][i];    }    printf("%d\n",big);    return 0;}
0 0
原创粉丝点击