问题大意:一个叫Bessie的牛,可以吃苹果,然后有两棵树,树上苹果每分钟会掉一个,这只牛一分钟可以在两棵树中往返吃苹果(且不吃地上的),然后折返只能是有限次W,问你这只叫Bessie的牛最多可以吃到多少个苹果
首先我们应该很容易想到,这个必须要用DP去做,然后就是考虑怎么储存旧值的问题了,因为树有两棵,然后每个往返状态对应不同的结果,所以我们应该用一个二维矩阵去储存(苹果的个数就不重要了,因为我们只用算到最后,前面的都可以扔掉)。
然后状态方程应该怎么写呢?也很简单,定义一个状态为dp[i][j]表示在第i棵树的剩余多少次转移机会时的能吃到苹果的最大个数,而牛可以从旁边一棵树走过来也可以是本来就在这棵树旁边
所以状态转移方程很自然的就是
dp[i][j]=max(dp[i][j],dp[i-1][j+1])+1 (j<w && i+1>w-j)
dp[i][j]=dp[i][j]+1;(j=w)
同时还要注意有一些状态是没有意义的,典型就是i+1<w-j的时候(你想一下苹果掉落的分钟数都比牛跑过来的次数还要少,怎么可能嘛!)
#include <stdio.h>
#include <stdlib.h>
#define MAX(a,b) (a)>(b)?(a):(b) static int Tree[][]; int main(void)
{
int T, W, i, k, Which_Tree, ans = ;
while (~scanf("%d%d", &T, &W))
{
for (i = ; i < T; i++)
{
scanf("%d", &Which_Tree);
Tree[Which_Tree - ][W]++;
for (k = W - ; k >= && i + > W - k; k--)
Tree[Which_Tree - ][k] =
MAX(Tree[!(Which_Tree - )][k + ] + , Tree[Which_Tree - ][k] + );
}
for (i = ; i < ; i++)
for (k = ; k <= W; k++)
ans = MAX(Tree[i][k], ans);
printf("%d", ans);
} return ;
}