题目大意
也蛮简单的 0时刻人在位置5,位置0-位置10会掉馅饼,人每个时间单位能动一格,动完或者不动之后可以拿到当前位置的馅饼,同一位置同时可能掉多个,问最多拿多少个馅饼
题解
转移方程dp[i][j]=max(dp[i-1][j-1]+pie[i][j],dp[i-1][j]+pie[i][j],dp[i-1][j+1]+pie[i][j]) 简单来说就是从上一个位置移动到下一个位置,加上这个位置能拿的馅饼就完了,实际上这个加法如果极限效率的话是可以提出来的,或者干脆就写到dp里也行,但这样会有一个问题,人在一开始只能是5,要注意在一开始不能从其他位置开始,要限制一下,我为了方便就分开来统计了
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 
 | #include<cstdio>#include<algorithm>
 #include<cstring>
 using namespace std;
 int dp[100020][12],pie[100020][12];
 int main(){
 int n;
 while(scanf("%d",&n),n){
 memset(dp,-1,sizeof(dp));
 memset(pie,0,sizeof(pie));
 dp[0][5]=0;
 int mtime=0;
 for(int i=0;i<n;++i){
 int p,t;
 scanf("%d%d",&p,&t);
 mtime=max(mtime,t);
 ++pie[t][p];
 }
 for(int i=1;i<=mtime;++i){
 if(dp[i-1][0]!=-1){
 dp[i][0]=max(dp[i][0],dp[i-1][0]+pie[i][0]);
 }
 if(dp[i-1][1]!=-1){
 dp[i][0]=max(dp[i][0],dp[i-1][1]+pie[i][0]);
 }
 for(int j=1;j<11;++j){
 for(int t=-1;t<2;++t){
 if(dp[i-1][j+t]!=-1){
 dp[i][j]=max(dp[i][j],dp[i-1][j+t]+pie[i][j]);
 }
 }
 }
 }
 int ans=0;
 for(int i=0;i<11;++i){
 ans=max(ans,dp[mtime][i]);
 }
 printf("%d\n",ans);
 }
 return 0;
 }
 
 |