Apple Catching(3维dp)

本文介绍了一个基于农民John的两棵苹果树的游戏问题,通过动态规划算法解决如何最大化Bessie捕获苹果的数量,同时考虑其移动限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



利用维度之间的联系降维

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

 题目是这样的:
输入7 表示1 ~ 7分钟, 输入的2 表示 能够从一棵树走到另一棵树的最多次数
接下来 7分钟,输入每分钟在第1 或者2棵树掉一个苹果, 可以不考虑从一棵树走到另一颗树的时间,但是最多只能行走2次(从A(B)树走到B (A)树,行走一次)

有一种状态,我以为错的 结果是我自己手算 错了,2333
这种状态表示为dp[i][j][k]前i颗树,行走最多j次的情况下,最后在第k代表的树,接下的最多的苹果

这道题 一开始建立3维的状态,发现始终不好处理第二维度和第三维度的联系关系 有bug
然后每一个二维对应着唯一的第三维 。所以直接压缩成二维的话好做多了
dp[i][j]表示
在前i分钟中,行走了j次的情况下得到的最大值,j为偶数表示对应最后位置在第一颗树 否则在第二颗树 
那么可以这么转移 dp[i][j] = max (dp[i-1][j], dp[i-1][j-1]);
然后再加上 最后走到dp[i][j]状态对应的树子掉落的苹果数(0或者1)
如果j = 0的时候,单独考虑,只能在第一棵树停留 那么就是dp[i][j] = dp[i-1][j] + (tree[i] == 1 ? 1 : 0);
具体过程见代码:
为了方便 把 第1 2颗树 映射成了第1 0棵树
//
// Create by Running Photon on 2015-03-05
//
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <algorithm>
#include <cctype>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <set>
#include <vector>
using namespace std;
#define CLR(x) memset(x,0,sizeof x)
#define ll long long
const int inf=0x3f3f3f3f;
const int maxn=1e3+5;
const int MOD=5e5+5;
int t, w;
int dp[maxn][35];//在前i分钟中,walk次数为j的情况下得到的最大值,walk为偶数表示在第一颗树 否则在第二颗树
int tree[maxn];
int main()
{
#ifdef LOCAL
 freopen("in.txt","r",stdin);
 //freopen("out.txt","w",stdout);
#endif
 ios_base::sync_with_stdio(0);
 while(scanf("%d%d", &t, &w)!=EOF){
        CLR(dp);
        for(int i = 1; i <= t; i++)
            scanf("%d", tree + i);
        for(int i = 0; i <= t; i++) for(int j = 0; j <= w; j++){
            dp[i + 1][j] = max(dp[i + 1][j], dp[i][j] + ((j + tree[i + 1]) & 1));
            dp[i + 1][j + 1] = max(dp[i + 1][j + 1], dp[i][j] + ((j + 1 + tree[i + 1]) & 1));//利用奇偶对照关系
        }
        int ans = -inf;
        for(int j = 0; j <= w; j++) {
            ans = max(ans, dp[t][j]);
        }
        printf("%d\n", ans);
 }
 return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值