坐标规划型动态规划
题目描述:
开始的位置是5;有0。1。2。。。9。10这11个点位置;
馅饼的掉落位置在这11个位置中,gameboy只能接到方圆1单位的馅饼;(移动一个单位需要一秒)
给出各个时间点T,馅饼掉落的位置;求最多接到多少个馅饼;(注意开始点是5);
状态转移方程:
dp[i][j] += max(dp[i+1][j],dp[i+1][j+1],dp[i+1][j-1])
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <string> #include <iomanip> #define N 100005 using namespace std; int dp[N][11]; int max(int a, int b) { return a>b?a:b; } int main(int argc, char *argv[]) { int n,x,T; while(scanf("%d",&n)&&n!=0) { memset(dp,0,sizeof(dp)); int maxt = 0; for(int i = 0; i < n; i++) { scanf("%d%d",&x,&T); dp[T][x]++; if(maxt < T) maxt = T; } for(int i = maxt; i >= 0; i--) { dp[i][0] += max(dp[i+1][0],dp[i+1][1]);//左边界考虑 for(int j = 1; j <= 9; j++) dp[i][j] += max(max(dp[i+1][j],dp[i+1][j+1]),dp[i+1][j-1]);//右边界考虑 dp[i][10] += max(dp[i+1][10],dp[i+1][9]); } printf("%d\n",dp[0][5]); } return 0; }
状态转移方程为:
dp[k][l] = max(max(dp[k][l-1],dp[k-1][l-1]),max(dp[k][l],dp[k+1][l-1]))+1;
则代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <string> #include <iomanip> #define maxn 110000 using namespace std; int dp[11][maxn]; struct bing { int x; int T; }boy[maxn]; int cmp(bing a, bing b) { return a.T<b.T; } int max(int a,int b) { return a>b?a:b; } int main(int argc, char *argv[]) { int n; while(scanf("%d",&n)&&n!=0) { for(int i = 0; i < n; i++) { scanf("%d%d",&boy[i].x,&boy[i].T); } sort(boy,boy+n,cmp); memset(dp,0,sizeof(dp)); int i; for(i = 0; i < n; i++) { if(boy[i].T!=0) break; else dp[5][0]++; } int k,l,maxnum = dp[5][0]; for(; i < n; i++) { k = boy[i].x,l = boy[i].T; if(k==0) dp[k][l] = max(max(dp[k][l-1],dp[k+1][l-1]),dp[k][l])+1; else if(k==10) dp[k][l] = max(max(dp[k][l-1],dp[k-1][l-1]),dp[k][l])+1; else dp[k][l] = max(max(dp[k][l-1],dp[k-1][l-1]),max(dp[k][l],dp[k+1][l-1]))+1; if(dp[k][l]>maxnum) maxnum = dp[k][l]; } printf("%d\n",maxnum); } return 0; }