poj 2385(经典DP 01背包 两种初始情况要处理的情况 )

Apple Catching
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 14701   Accepted: 7198

Description

It is a little known fact that cows love apples. Farmer John has two apple trees (which are conveniently numbered 1 and 2) in his field, each full of apples. Bessie cannot reach the apples when they are on the tree, so she must wait for them to fall. However, she must catch them in the air since the apples bruise when they hit the ground (and no one wants to eat bruised apples). Bessie is a quick eater, so an apple she does catch is eaten in just a few seconds. 

Each minute, one of the two apple trees drops an apple. Bessie, having much practice, can catch an apple if she is standing under a tree from which one falls. While Bessie can walk between the two trees quickly (in much less than a minute), she can stand under only one tree at any time. Moreover, cows do not get a lot of exercise, so she is not willing to walk back and forth between the trees endlessly (and thus misses some apples).

Apples fall (one each minute) for T (1 <= T <= 1,000) minutes. Bessie is willing to walk back and forth at most W (1 <= W <= 30) times. Given which tree will drop an apple each minute, determine the maximum number of apples which Bessie can catch. Bessie starts at tree 1.

Input

* Line 1: Two space separated integers: T and W 

* Lines 2..T+1: 1 or 2: the tree that will drop an apple each minute.

Output

* Line 1: The maximum number of apples Bessie can catch without walking more than W times.

Sample Input

7 2
2
1
1
2
2
1
1

Sample Output

6

Hint

INPUT DETAILS: 

Seven apples fall - one from tree 2, then two in a row from tree 1, then two in a row from tree 2, then two in a row from tree 1. Bessie is willing to walk from one tree to the other twice. 

OUTPUT DETAILS: 

Bessie can catch six apples by staying under tree 1 until the first two have dropped, then moving to tree 2 for the next two, then returning back to tree 1 for the final two.


题目要求:在移动次数不超过W次的前提下,怎样在T分钟内获得的苹果数最多。

DP嘛,肯定有状态转移方程的,dp[i+1][j]=max(dp[i][j],dp[i][j-1]);

dp[i+1][j]指前i+1分钟内移动次数为j所得苹果的最多的数量,可以看成容量为W,每个物品价值与质量都是1的01背包。

上code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
#define MAXN 40005
#define mem(a,b) memset(a,b,sizeof(a));
int dp[1002][31];
int a[1005];
int main()
{
    mem(dp,0);
    int t,n;
    cin>>t>>n;
    for(int i=1;i<=t;i++)
        cin>>a[i];
        dp[1][0]=a[1]%2;//初始化前一分钟不移动的情况下,是多少只能看a[1]是指的第几课树
        dp[1][1]=(a[1]+1)%2;//不加这一句是错的,因为你还要看看另一棵树的情况,因为这是两棵树,默认开始是在1号树下,拿就要看看移动一次
    for(int i=1;i<=t;i++)//到2号树的情况是不是能够有苹果,可以想象成是两种不可以少的初始情况,对与dp来说一定要将所有的初始情况考虑到
    {                         //第二种情况我是没能想到。
        for(int j=0;j<=n;j++)
        {
            if(j==0)//不移动的情况,dp就是前i分钟与此时哪棵树落苹果的情况了
                dp[i+1][j]=dp[i][j]+a[i+1]%2;
            else{
                dp[i+1][j]=max(dp[i][j],dp[i][j-1]);//当要看移动的情况的时候,不止要看前i分钟的情况,还要加上你移动到j+1号树
             if(j%2+1==a[i+1])//的有无苹果的情况,如果此时的移动正好掉苹果,那就dp++
                dp[i+1][j]++;}
        }
    }
//    for(int i=0;i<=t+1;i++)
//    {
//        for(int j=0;j<=n;j++)
//            cout<<dp[i][j]<<" ";
//        cout<<endl;
//    }
        cout<<dp[t+1][n]<<endl;
    return 0;
}
还有另一种处理方法 点击打开链接

猜你喜欢

转载自blog.csdn.net/c___c18/article/details/80831419