poj 2385 来回走接苹果dp

来源:互联网 发布:什么是双色球密码算法 编辑:程序博客网 时间:2024/05/18 01:25

题意:

有两棵树,奶牛开始时在树1下,现在每分钟两棵树中的某一棵会下苹果,奶牛只可以移动w次。

给每分钟下苹果的顺序,问奶牛最多能拿到多少苹果。


解析:

dp[ i ] [ j ] 表示的是在第i分钟,移动了w次拿到的最多苹果。

因为奶牛初始在树1下,所以:

dp[i][0] = dp[i - 1][0] + (a[i] == 1 ? 1 : 0);
状态转移方程:

dp[i][j] = max(dp[i - 1 ] [j], dp[i-1][j-1]) + cnt

在第i分钟奶牛到某棵树下有两种状态:

从另一棵树走过来(dp[i-1][j-1]);

本来就呆在这棵树下(dp[i-1][j])。


所以在第i分钟时能接到的最大苹果数就是

dp[i][j]=max(dp[ i - 1 ] [ j ], dp[ i - 1 ] [ j - 1 ]) + cnt。

cnt的值:

如果j为偶数说明她移动了j次又回到了第一棵树下,则cnt = (a[i]==1)?1:0;

若j为奇数说明她移动了j次后到了第二棵树下,则 cnt =(a[i] == 2)?1:0。


代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 1e6 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int dp[1001][31];int a[1001];int main(){#ifdef LOCAL    freopen("in.txt", "r", stdin);#endif // LOCAL    int t, w;    while (~scanf("%d%d", &t, &w))    {        for (int i = 1; i <= t; i++)        {            scanf("%d", &a[i]);        }        memset(dp, 0, sizeof(dp));        for (int i = 1; i <= t; i++)        {            dp[i][0] = dp[i - 1][0] + (a[i] == 1 ? 1 : 0);            for (int j = 1; j <= w; j++)            {                int cnt = 0;                if (j & 1)                {                    cnt = (a[i] == 1) ? 0 : 1;                }                else                {                    cnt = (a[i] == 2) ? 0 : 1;                }                dp[i][j] = max(dp[i - 1][j - 1], dp[i - 1][j]) + cnt;            }        }        int ans = 0;        for (int i = 1; i <= w; i++)        {            ans = max(ans, dp[t][i]);        }        printf("%d\n", ans);    }    return 0;}


0 0