链接:http://acm.hdu.edu.cn/showproblem.php?pid=1176
转移方程:
dp[i][j] = s[i][j]+max(dp[i-1][j],max(dp[i-1][j-1],dp[i-1][j+1]));不过后来发现根本不需要这样开两个直接在原来的数组上处理就可以了。。
还有就是其实倒着来做比较方便,这个就是类似数塔问题的。。。正着做一开始只能移动到4或者6,慢慢才会扩展出去
渣代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 100009
#define INF 0x3f3f3f3f
int dp[M][11];
int s[M][11];
int main()
{
int n;
while(scanf("%d",&n)==1 && n)
{
memset(s,0,sizeof(s));
int t = -INF;
for(int i = 0;i < n;i++)
{
int a,b;
scanf("%d %d",&a,&b);
if(b>t) t = b;
s[b][a]++;
}
memset(dp,0,sizeof(dp));
int maxn = -INF;
int a = 4,b = 6;
for(int i = 1;i <= t;i++)
{
for(int j = a;j <= b;j++)
{
if(j>0&&j<10)
dp[i][j] = s[i][j]+max(dp[i-1][j],max(dp[i-1][j-1],dp[i-1][j+1]));
else if(j==0) dp[i][j] = s[i][j]+max(dp[i-1][j],dp[i-1][j+1]);
else if(j==10) dp[i][j] = s[i][j]+max(dp[i-1][j],dp[i-1][j-1]);
//if(dp[i][j]>maxn)
//maxn = dp[i][j];
}
if(a-1>=0) a = a-1;
if(b+1<=10) b = b+1;
}
for(int i = 0;i <= 10;i++)
if(dp[t][i]>maxn) maxn = dp[t][i];
printf("%d\n",maxn);
}
return 0;
}
这基本就是数塔问题的模型了,倒着做比较方便~~
倒着做别人的代码:
#include<cstdio>
#include<cstring>
using namespace std;
#define max(a,b) (a)>(b)?(a):(b)
#define N 100005
int dp[N][11];
int main()
{
int n,x,t,i,j,maxt;
while(scanf("%d",&n)&&n)
{
memset(dp,0,sizeof(dp));
maxt=0;
for(i=1;i<=n;i++)
{
scanf("%d%d",&x,&t);
dp[t][x]++;
if(maxt<t) maxt=t;
}
for(i=maxt-1;i>=0;i--)
{
dp[i][0]+=max(dp[i+1][0],dp[i+1][1]);//左边界特殊考虑
for(j=1;j<=9;j++)
dp[i][j]+=max(max(dp[i+1][j-1],dp[i+1][j]),dp[i+1][j+1]);
dp[i][10]+=max(dp[i+1][9],dp[i+1][10]);//右边界特殊考虑
}
printf("%d\n",dp[0][5]);
}
return 0;
}