版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/PK__PK/article/details/81631720
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1176
题意:中文题意不解释
题解:定义DP【i】【j】 为 第 i 秒 在 j 位置接到东西的最大值。
所以转移方程为
DP【i】【j】 = max (DP【i-1】【j】,DP【i-1】【j-1】,DP【i-1】【j+1】)+ a【i】【j】
因为能移动距离为1的位置,所以比较好推出来。不过特殊考虑一下0位置和10位置,0位置需要没法向左走,10位置没法向右走。
看代码
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int a[100001][12]; //
int f[100001][12]; // f【i】【j】表示第i秒时j位置能接到的最大值。
int main(){
int n;
while(scanf("%d", &n) != EOF && n){
memset(a, 0, sizeof(a));
memset(f, 0, sizeof(f));
int x, T, i, j, maxT = 0, ans = 0;
while(n--){
scanf("%d%d", &x, &T);
++a[T][x];
maxT = max(maxT, T); //统计最大时间
}
f[1][4] = a[1][4]; // 初始位置在5 ,所以第一秒能接到4,5,6位置的东西。
f[1][5] = a[1][5];
f[1][6] = a[1][6];
for(i = 2; i <= maxT; ++i){ // 从第二秒开始
for(j = 0; j < 11; ++j){ // 从0位置开始
f[i][j] = f[i - 1][j];
if(j > 0)
f[i][j] = max(f[i][j], f[i - 1][j - 1]); // 若j == 0 则,没办法向左走。
if(j < 10)
f[i][j] = max(f[i][j], f[i - 1][j + 1]); // 若 j == 10 ,没办法向右走。
f[i][j] += a[i][j]; //获得该位置的东西。
//printf("%d ", f[i][j]);
}
//printf("\n");
}
for(i = 0; i < 11; ++i) // 取出最大值。
ans = max(ans, f[maxT][i]);
printf("%d\n", ans);
}
return 0;
}