http://poj.org/problem?id=2385
Description
有两棵APP树,编号为1,2.每一秒,这两棵APP树中的其中一棵会掉一个APP.每一秒,你可以选择在当前APP树下接APP,或者迅速移动到另外一棵APP树下接APP(移动时间可以忽略不计),但由于却乏锻炼,你最多移动W次.问在T秒内,你最多能收集多少个APP.假设你开始站在1号APP树下.
Input
第1行:两个整数T(1 < = T< = 1000)和W(1 < = W< = 30)
第2..T+1行:1或2,代表每分钟掉落APP的那棵树的编号
Output
一行一个整数,代表你移动不超过W次能接住的最大APP数
Sample Input
7 2 2 1 1 2 2 1 1
Sample Output
6
思路:dp[i][j]代表第i时间,换j次得到的最多苹果
注意a初始化,dp初始化,还有数组的大小,死了还久,希望下次不会了。。。。。。
代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[1010][40];
int main()
{
int n,m; int a[1010][2];
while(scanf("%d%d",&n,&m)!=EOF)
{
int b;
for(int i=1;i<=n;i++)
{
scanf("%d",&b);
a[i][b]=1;
a[i][b%2+1]=0;
}
if(a[1][1]==1)
{
dp[1][0]=1;
dp[1][1]=0;
}
else
{
dp[1][0]=0;
dp[1][1]=1;
}
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
if(j==0)
{
dp[i][j]=dp[i-1][j]+a[i][1];
}
else if(j%2==1)
{
dp[i][j]=max(dp[i-1][j-1]+a[i][1],dp[i-1][j]+a[i][2]);
}
else
dp[i][j]=max(dp[i-1][j-1]+a[i][2],dp[i-1][j]+a[i][1]);
ans=max(dp[i][j],ans);
}
}
printf("%d\n",ans);
}
return 0;
}
代码2
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1111;
int dp[maxn][35];
int a[maxn];
int main()
{
int t, w;
while(~scanf("%d%d", &t, &w))
{
for(int i = 1; i <= t; i++)
scanf("%d", &a[i]);
if(a[1] == 1)
{
dp[1][0] = 1;
dp[1][1] = 0;
}
else
{
dp[1][0] = 0;
dp[1][1] = 1;
}
for(int i = 2; i <= t; i++)
{
for(int j = 0; j <= w; j++)
{
if(j == 0) dp[i][j] = dp[i-1][j] + a[i]%2;
else
{
dp[i][j] = max(dp[i-1][j], dp[i-1][j-1]);
if(j%2+1 == a[i]) dp[i][j]++;
}
}
}
int ans = 0;
for(int i = 0; i <= w; i++)
ans = max(ans, dp[t][i]);
printf("%d\n", ans);
}
return 0;
}