NOJ1060 接苹果 二维DP

题目描述

很少有人知道奶牛爱吃苹果。农夫约翰的农场上有两棵苹果树(编号为1和2), 每一棵树上都长满了苹果。奶牛贝茜无法摘下树上的苹果,所以她只能等待苹果 从树上落下。但是,由于苹果掉到地上会摔烂,贝茜必须在半空中接住苹果(没有人爱吃摔烂的苹果)。贝茜吃东西很快,她接到苹果后仅用几秒钟就能吃完。每一分钟,两棵苹果树其中的一棵会掉落一个苹果。贝茜已经过了足够的训练, 只要站在树下就一定能接住这棵树上掉落的苹果。同时,贝茜能够在两棵树之间 快速移动(移动时间远少于1分钟),因此当苹果掉落时,她必定站在两棵树其中的一棵下面。此外,奶牛不愿意不停地往返于两棵树之间,因此会错过一些苹果。苹果每分钟掉落一个,共T(1<=T<=1000)分钟,贝茜最多愿意移动W(1<=W<=30)
次。现给出每分钟掉落苹果的树的编号,要求判定贝茜能够接住的最多苹果数。 开始时贝茜在1号树下。

输入

第一行2个数,t和k。接下来的t行,每行一个数,代表在时刻t苹果是从1号苹果树还是从2号苹果树上掉下来的。

输出

对于每个测试点,输出一行,一个数,为奶牛最多接到的苹果的数量。

输入样例

7 2

2

1

1

2

2

1

1

输出样例

6(输出注解:贝茜不移动直到接到从第1棵树上掉落的两个苹果,然后移动到第2棵树下,直到接到从第2棵树上掉落的两个苹果,最后移动到第1棵树下,接住最后两个从第1 棵树上掉落的苹果。这样贝茜共接住6个苹果。)

解题思路

这是一题二维DP  我们用dp[i][j]表示到前i个苹果,换了j次的最大苹果数量。

假设我们现在已经考虑完了i-1的情况。

那么如果第i个苹果我们移动:有dp[i][j] = dp[i-1][j-1] + 当前位置是否有苹果(0或1)

如果第i个苹果我们不移动:有dp[i][j] = dp[i-1][j] + 当前位置是否有苹果(0or1)

(当前位置:换了j次 如果j是奇数  那么奶牛肯定在2号树   如果j是偶数 那么奶牛肯定是在1号树)

下面我们考虑一下dp的初始化。做了几道DP问题之后我发现DP问题最难的地方在建立DP数组 而最需要小心的地方则是DP数组的初始化,这题就跳进了一个陷阱。。。幸好及时发现了。

从状态转移方程我们知道要初始化dp[x][0]和dp[1][x]

dp[x][0] 即不移动 一直在1号树下面 能接到多少自己脑补。。。

dp[1][x]即只考虑第一个苹果 奶牛在下面移来移去。。。自己脑补

下面放代码

#include <cstdio>
#include <cstring>
#include <algorithm>
const int maxpingguo= 1010;
const int maxyidong = 35;
using namespace std;
int dp[maxpingguo][maxyidong];
int apple[maxpingguo][3];//apple[i][j]=1为在第i分钟j树上有苹果 这样设计apple数组为下面的DP创造方便
int main()
{
    int pingguo,yidong;
    scanf("%d%d",&pingguo,&yidong);
    for(int i = 1 ; i <= pingguo ; i ++) {
        int t;
        scanf("%d",&t);
        apple[i][t] = 1;
    }
    //dp初始化
    for(int i = 1 ; i <= yidong ; i ++) {
        if(i%2) {
            if(apple[1][2]) dp[1][i] = 1;
            else dp[1][i] = 0;
        }else {
            if(apple[1][1]) dp[1][i] = 1;
            else dp[1][i] = 0;
        }
    }
    for(int i = 1  ; i <= pingguo ; i ++) {/*这里有一个陷阱,一开始我觉得上面已经初始化过dp[1][1]了 所以直接从i=2走起了
                                            *但实际上如果yidong=0的情况下上面的初始化并不会执行!!
                                            */
        dp[i][0] = dp[i-1][0] +apple[i][1];
    }
    //dp
    for(int j = 1 ; j <= yidong ; j ++) {
        for(int i = 2 ; i <= pingguo ; i ++) {
            if(j%2) {
                dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]) +apple[i][2];
            }else {
                dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]) +apple[i][1];
            }
        }
    }
    int _max = -1;
    for(int i = 0 ; i <= yidong ; i ++) {
        if(_max < dp[pingguo][i]) _max = dp[pingguo][i];
    }
    printf("%d\n",_max);
    return 0;
}
时间: 2024-12-11 20:42:40

NOJ1060 接苹果 二维DP的相关文章

HDU 4901 The Romantic Hero(二维dp)

题目大意:给你n个数字,然后分成两份,前边的一份里面的元素进行异或,后面的一份里面的元素进行与.分的时候按照给的先后数序取数,后面的里面的所有的元素的下标一定比前面的大.问你有多上种放元素的方法可以使得前面异或的值和后面与的值相等. dp[x][y] 表示走到第x步,得到y这个数字一共有多少种方法. 但是需要注意这里得分一下,不能直接用dp数组存种数,你需要分一下从上一层过来的次数,和这一层自己可以到达的次数.然后取和的时候前后两个集合的种数进行乘法,注意边乘边取余. 顺便给一组数据: 4 3

二维dp(O(N^3)实现) zoj3230

1 #include<iostream> 2 #include<string.h> 3 #include<stdio.h> 4 #define maxn 125 5 using namespace std; 6 7 int cost[maxn][maxn],w[maxn][maxn]; 8 int dp[maxn][maxn]; 9 int N,M; 10 int main(){ 11 while(cin>>N>>M){ 12 if (N==0

hoj_10014_二维DP

The Triangle Time Limit: 1000ms, Special Time Limit:2000ms, Memory Limit:32768KB Total submit users: 952, Accepted users: 860 Problem 10014 : No special judgement Problem description 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 (Figure 1) Figure 1 shows a number tr

XTU1168:Alice and Bob(二维DP)

摘要:Dota(Defence of the Ancients,远古的守护), 是指基于魔兽争霸3:冰封王座(暴雪娱乐公司出品)的多人即时对战自定义地图,可支持10个人同时连线游戏.Dota以对立的两个小队展开对战,通常是5v5,游戏目的是守护自己的远古遗迹(近卫方的生命之树.天灾方的冰封王座),同时摧毁对方的远古遗迹.DotA是目前唯一被暴雪娱乐公司官方认可的魔兽争霸RPG.Dota在大学生中的风靡程度令人咂舌,而随着玩家对游戏的理解深入,本身存在于游戏中的许多数学模型被挖掘出来进行研究.游戏

HDU 5074 Hatsune Miku(简单二维dp)

题目大意:给你一些音符之间的联系,给你一个串,让你求出这个串的最大值.-1的时候可以任意替代,其他情况必须为序列上的数. 解题思路:简单二维dp,分情况处理就可以了啊. Hatsune Miku Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 637    Accepted Submission(s): 458 Problem De

(review)zoj4800 二维dp 状态转移很灵活

1 #include<iostream> 2 #include<stdio.h> 3 4 using namespace std; 5 6 double dp[10005][125]; 7 double p[125][125]; 8 int pk[10005]; 9 10 int N,M; 11 12 double fmax(double a,double b){ 13 if(a-b>0) return a;else return b; 14 } 15 int main(){

洛谷p1732 活蹦乱跳的香穗子 二维DP

今天不BB了,直接帖原题吧  地址>>https://www.luogu.org/problem/show?pid=1732<< 题目描述 香穗子在田野上调蘑菇!她跳啊跳,发现自己很无聊,于是她想了一个有趣的事情,每个格子最多只能经过1次,且每个格子都有其价值 跳的规则是这样的,香穗子可以向上下左右四个方向跳到相邻的格子,并且她只能往价值更高(这里是严格的大于)的格子跳. 香穗子可以从任意的格子出发,在任意的格子结束, 那么她最多能跳几次? 输入输出格式 输入格式: 第一行n,m,

二维dp

原题http://acm.hdu.edu.cn/showproblem.php?pid=3127 WHUgirls Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 2050    Accepted Submission(s): 780 Problem Description There are many pretty girls i

Astar_D_二维DP

Labyrinth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2911    Accepted Submission(s): 1007 Problem Description 度度熊是一只喜欢探险的熊,一次偶然落进了一个m*n矩阵的迷宫,该迷宫只能从矩阵左上角第一个方格开始走,只有走到右上角的第一个格子才算走出迷宫,每一次只能走一格