题目大意
也蛮简单的 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,要注意在一开始不能从其他位置开始,要限制一下,我为了方便就分开来统计了
1 2 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; }
|