P2690 [USACO04NOV]Apple Catching G

https://www.luogu.com.cn/problem/P2690
涉及知识点:动态规划DP,搜索
黄色题
 
思路:

这道题简单的地方有两个:一是数据范围小,二是在不用管大小的情况下方程十分好想。但仍然有一些小细节让我错了两回。 分析过程:

1.问啥设啥。

......时的最大接苹果数;这里我们发现题目设定上有两个比较明显的变量:总数和移动次数。于是先无脑把他们设出来!于是得

f[落下多少个][移动几次];

2.想转移方程,进行补充。

那么这个方程的上一种状态是什么呢?首先捡不捡不一定,但上种状态落下的果子肯定少一,所以第一维是i-1;那么他到底有没有移动呢?我们自然会想到会有以下情况: ①他从另一棵树移过来并且接到了果子;

②他从另一棵树移过来但没接到果子;

③他站着不动接到了一颗果子;

④他站着不动也没接到果子;

但他到底有没有接到果子呢???我们并不知道他现在在哪里,所以也不知道他有没有接到果子,于是我们决定多加一维来表示他所在的位置。于是得

f[落下多少个][移动次数][现在所处位置]

我发现人刚开始在第一棵树下,那就意味着移动奇数次时人一定在二号树下,偶数次时人一定在一号树下!二者不能同时被修改!所以方程改为:

复制代码
if(a[i]==1) { if(j%2==0) f[i][j][1]=max(f[i-1][j-1][2],f[i-1][j][1])+1; else f[i][j][2]=max(f[i-1][j][2],f[i-1][j-1][1]); } if(a[i]==2) { if(j%2==1) f[i][j][2]=max(f[i-1][j-1][1],f[i-1][j][2])+1; else f[i][j][1]=max(f[i-1][j][1],f[i-1][j-1][2]); }
复制代码

但移动次数越多并不代表接到的苹果数越多,所以要遍历所有移动次数找最大值

复制代码
#include<bits/stdc++.h> using namespace std; int t,w; int a[1009]; int f[1009][35][3];//落到第几个,移动几次,当前在哪棵树下 ///时的最大接苹果数 int main() { cin>>t>>w; for(int i=1;i<=t;i++){ cin>>a[i]; } for(int i=1;i<=t;i++){ for(int j=0;j<=w;j++){ if(a[i]==1) { if(j%2==0)//偶数 { f[i][j][1]=max(f[i-1][j-1][2],f[i-1][j][1])+1; } else f[i][j][2]=max(f[i-1][j][2],f[i-1][j-1][1]); } if(a[i]==2) { if(j%2==1) { f[i][j][2]=max(f[i-1][j-1][1],f[i-1][j][2])+1; } else f[i][j][1]=max(f[i-1][j][1],f[i-1][j-1][2]); } } } int ans=-1; for(int j=0;j<=w;j++) { ans=max(ans,max(f[t][j][1],f[t][j][2])); } cout<<ans; return 0; }
复制代码

注:在前一时刻i-1中,只有两种情况可以到达f[i][j][1]

一. f[i-1][j][1]

二.f[i-1][j-1][2]

__EOF__

本文作者灰の魔女伊蕾娜
本文链接https://www.cnblogs.com/2elaina/p/16518550.html
关于博主:编程小萌新一名,希望从今天开始慢慢提高,一步步走向技术的高峰!
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   -イレイナ  阅读(56)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示