北大ACM——2385,Apple Catching(DP)

dp[T,W,N]: 在T分钟,移动次数剩余W次时,在第N棵树下可以拿到的苹果的最大数量。
简化:
一开始因为奶牛是在第一棵树,而苹果树只有两棵,因此奶牛的位置可以由剩余移动次数W来确定,故
dp[T,W,N] → dp[T,W]: 在T分钟,移动次数剩余W次时,奶牛可以拿到的最大苹果数。
设置数组a[T],记录T时间哪个位置有苹果。
状态转移方程:
if(a[i]==1)
{
if(W与W0奇偶性相同,就可以拿苹果)
dp[T,W]=max(dp[T-1,W]+1,dp[T-1,W+1]+1) //T-1时就在1位置,或者T-1时从2过来拿苹果
else
dp[T,W]=max(dp[T-1,W],dp[T-1,W+1])
}
if(a[i]==2)
{
同理
}

代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[1001][31];
int a[1001]; 
int main()
{
	int T,W,i,j;
	int ans=0,flag;
	memset(dp,0,sizeof(dp));
	memset(a,0,sizeof(a));
	scanf("%d%d",&T,&W);
	if(W%2==0) flag=0;   //flag=0,W为偶数,flag=1,W为奇数
	else flag=1;
	for(i=1;i<=T;i++)
		scanf("%d",&a[i]);
	for(i=1;i<=T;i++)
	{
		for(j=W;j>=0;j--)
		{
		    if(a[i]==1)   //第一棵树有苹果 
			{
				if(j!=W)  //边界,注意一下,小心越界了
				{
					if(flag==1)
					{
					    if(j%2==1)
					    dp[i][j]=max(dp[i-1][j]+1,dp[i-1][j+1]+1);
					    else dp[i][j]=max(dp[i-1][j],dp[i-1][j+1]);
					}
					else
					{
						if(j%2==0)
					    dp[i][j]=max(dp[i-1][j]+1,dp[i-1][j+1]+1);
					    else dp[i][j]=max(dp[i-1][j],dp[i-1][j+1]);
					}
				}
				else if(j==W)
				dp[i][j]=dp[i-1][j]+1;
			}
			else  //第二棵树有苹果 
			{
				if(j!=W)
				{
					if(flag==1)
					{
					    if(j%2==0)
					    dp[i][j]=max(dp[i-1][j]+1,dp[i-1][j+1]+1);
					    else dp[i][j]=max(dp[i-1][j],dp[i-1][j+1]);
				    }
					else
					{
						if(j%2==1)
					    dp[i][j]=max(dp[i-1][j]+1,dp[i-1][j+1]+1);
					    else dp[i][j]=max(dp[i-1][j],dp[i-1][j+1]);
					}
				}
			}
		}
	}
	for(i=W;i>=0;i--)
	    if(ans<dp[T][i])
	        ans=dp[T][i];
	printf("%d\n",ans);
	return 0;
}

一些测试样例:
7 2
2
1
1
2
2
1
1
6
7 3
2
1
1
2
2
1
1
6
7 4
2
1
1
2
2
1
1
7
8 4
2
2
1
1
2
1
2
1
7
8 1
2
2
2
1
1
2
1
2
5
8 2
2
2
2
1
1
2
1
2
6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值