洛谷 P2690 [USACO04NOV]Apple Catching G

题目大意:

奶牛喜欢吃苹果。约翰有两棵苹果树,有 N 只苹果会从树上陆续落下。如果掉苹果的时候,贝西在那棵树下,她就能接住苹果。贝西一开始在第一棵树下。在苹果掉落之前,她有足够的时间来回走动,但她很懒,最多只愿意移动 K 次。请计算一下她最多可以接住几只苹果。

分析:

首先很明显这是一道动态规划的问题(一开始脑子抽了做了个背包发现状态转移极为麻烦)

分析题目,发现决定每一种状态的关键变量仅为 当前的时间跳动的次数。因此,我们建立一个二维的 \(dp[i][j]\),表示当时间为 \(i\),总共跳动了 \(j\) 次的时候能够摘到的最多的果实。

在每一刻时间,我们可以选择转移到另一棵树下,也可以选择不进行转移,这就提示我们每个 \(dp[i][j]\) 可以从 \(dp[i - 1][j]\)\(dp[i - 1][j - 1]\) 转移过来。同时,如果在当前时刻,所在的树上掉落了一个果实,那么我们就可以得到这个果实,答案加一。
综上,我们有如下的状态转移方程:

\[\begin{cases} dp[i][j] = \max(dp[i - 1][j,dp[i - 1][j - 1]) \\ dp[i][j] += 1 &\text{j % 2 + 1 == a[i]} \\ \end{cases} \]

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
int n,k,dp[MAXN][MAXN],a[MAXN];
int main(){
   cin >> n >> k;
   for(int i = 1;i <= n; i++){
   	cin >> a[i];
   }
   for(int i = 1; i <= n; i++){
   	for(int j = 0; j <= k; j++){
   		if(j == 0)dp[i][j] = dp[i - 1][j];
   		else dp[i][j] = max(dp[i - 1][j],dp[i - 1][j - 1]);
   		if(j % 2 + 1 == a[i])dp[i][j]++;
   	}
   }
   int ans = 0;
   for(int i = 0; i <= k; i++){
   	ans = max(ans,dp[n][i]);
   }
   cout << ans;
}
posted @ 2022-07-25 22:07  腾云今天首飞了吗  阅读(110)  评论(0编辑  收藏  举报