View Code
//hdu 1176 dp(数塔) //简单dp,刚在练dp,一些小错误,纠结了好就 //可以从前往后推 也可以从后往前推 //我是从前(时间 为1, 位置为5)往后推的,这样比较纠结,还要限制 //前几步不能走太远,因为一秒只能移动一格,要记录最优值 //如果从最后一秒往前推的话,可以省掉一些判断,结果直接输出dp[0][5]就可以了 #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <algorithm> using namespace std; #define N 100005 //前一维表示时间,后一维表示坐标 int cake[N][15], dp[N][15]; int main() { int n_cake; while(scanf("%d", &n_cake), n_cake) { memset(cake, 0, sizeof(cake)); memset(dp, 0, sizeof(dp)); int max_t = 0; while(n_cake--) { int point, time; scanf("%d%d", &point, &time); cake[time][point]++; //记录time时间在point点掉几块 max_t = max(max_t, time); //记录最大时间 } int max_cake = 0; //第一重循环表示在 时间 i 的时候 //第二重循环表示 时间 i 时,人在 j 位置 for(int i = 1; i <= max_t; ++i) { for(int j = 0; j <= 10; ++j) { //记录时间 i-1 时 j 位置的 cake 数 int num = dp[i-1][j]; //记录前一时刻所能到 i时刻 j 位置的状态下,最多的cake数 if(j != 0) num = max( num, dp[i-1][j-1] ); if(j != 10) num = max( num, dp[i-1][j+1] ); dp[i][j] = num; //i 时刻 j位置为 前一状态 最优值 加上 现在状态的值 if( cake[i][j] && i >= abs(j - 5) ) //表示从 5 开始,比如时间为 1时到不了3 dp[i][j] += cake[i][j]; // if(i == 1 && (j < 4 || j > 6)) //判断前几步时不能这样判断,不过 // continue; //这题的数据太水,被我水过了 max_cake = max(max_cake, dp[i][j]); } } printf("%d\n", max_cake); } return 0; }