我还记得第一次做这个题的时候,刚学dp的我理解了很长时间,现在5个月过去了,现在dp只会基础背包问题,回过头来再学一遍吧,那时的我那么菜,现在的我还是那么菜,将来的我不能继续菜下去了。
题意:天上掉馅饼,你每秒最多移动一个单位,你最多能得到多少个馅饼。
思路:每一个状态,都由前一个状态得来,这一秒都是由上一秒取最优+这一秒能得到的数量。还是dp思想
我的AC代码:
#include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<vector> #include<map> #include<string> #define LL long long #define eps 1e-8 using namespace std; const int mod = 1e7+7; const int INF = 1e8; const int inf = 0x3f3f3f3f; const int maxx = 100100; const int N = 1050; int n,b,c; int dp[maxx][12]; int a[maxx][12]; int ma(int o,int p,int q) { int l=o; if(p>l) l=p; if(q>l) l=q; return l; } int main() { while(~scanf("%d",&n)) { if(n==0) break; int time=0; memset(a,0,sizeof(a)); memset(dp,-inf,sizeof(dp)); dp[0][5]=0; for(int i=0; i<n; i++) { scanf("%d%d",&b,&c); if(c>time) time=c; a[c][b]++; } for(int i=1; i<=time; i++) { dp[i][0]=max(dp[i-1][0],dp[i-1][1])+a[i][0]; for(int j=1; j<10; j++) dp[i][j]=ma(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1])+a[i][j]; dp[i][10]=max(dp[i-1][10],dp[i-1][9])+a[i][10]; } int ans=0; for(int i=0; i<=10; i++) { if(dp[time][i]>ans) ans=dp[time][i]; } printf("%d\n",ans); } }看博客的另一种更好的思路:
#include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<vector> #include<map> #include<string> #define LL long long #define eps 1e-8 using namespace std; const int mod = 1e7+7; const int INF = 1e8; const int inf = 0x3f3f3f3f; const int maxx = 100100; const int N = 1050; int n,b,c; int dp[maxx][12]; int a[maxx][12]; int ma(int o,int p,int q) { int l=o; if(p>l) l=p; if(q>l) l=q; return l; } int main() { while(~scanf("%d",&n)) { if(n==0) break; int time=0; memset(a,0,sizeof(a)); memset(dp,0,sizeof(dp)); for(int i=0; i<n; i++) { scanf("%d%d",&b,&c); if(c>time) time=c; a[c][b+1]++; } for(int i=time; i>=0; i--) for(int j=1; j<=11; j++) dp[i][j]=ma(dp[i+1][j-1],dp[i+1][j],dp[i+1][j+1])+a[i][j]; printf("%d\n",dp[0][6]); } }