您的位置:首页 > 移动开发

POJ 2385 Apple Catching DP

2013-08-29 10:33 375 查看
简单DP

用dp[i][j]表示第i个苹果掉落,刚好走了j步能吃到苹果的最大值

读入时把两颗树的标号1,2处理成0,1,以下说的树的编号都是处理后的0,1;

用num[i][2]来记录第i个秒掉落在两颗数的苹果个数,掉落在树0,则num[i][0]=1,num[i][1]=0,掉落在树1,则num[i][1]=1,num[i][0]=0;(num[]数组记得初始化);

dp[][]数组初始值:

if(num[1][0]==1)dp[1][0]=1;
dp[1][1]=1;


状态转移:

当j=0时,dp[i][j]的前一个状态只能是原地不动(且一定在树0位置)dp[i-1][j],所以dp[i][j]=dp[i-1][j]+num[i][0](num[i][0]表示第i秒掉路在树0的苹果数);
当j!=0时,根据j的奇偶性可以判断走到了哪一棵树,走到了树(j&1)。dp[i][j]的前的状态有2个:

状态1:没有移动dp[i-1][j];

状态2:移动了dp[i-1][j-1];

状态转移方程为:

if(j==0)dp[i][j]=dp[i-1][j]+num[i][0];
               
else dp[i][j] = max(dp[i-1][j],dp[i-1][j-1])+num[i][j&1];


最后枚举所有dp
[i](i表示步数),求其中的最大值。

AC代码:




View Code

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[1003][34];
int num[1003][2];
int n,m;
int main()
{
int i, j, tmp;
while(~scanf("%d%d",&n,&m))
{
memset(num,0,sizeof(num));
for(i=1;i<=n;i++)
{
scanf("%d",&tmp);
num[i][tmp-1]++;
}
memset(dp,0,sizeof(dp));
if(num[1][0]==1)dp[1][0]=1;
dp[1][1]=1;
for(i=2;i<=n;i++)
{
for(j=0;j<=m;j++)
{
if(j==0)dp[i][j]=dp[i-1][j]+num[i][0];
else dp[i][j] = max(dp[i-1][j],dp[i-1][j-1])+num[i][j&1];
}
}
int ans=0;
for(i=0;i<=m;i++)
ans = max(ans,dp
[i]);
printf("%d\n",ans);
}
return 0;
}


 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: