链接: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;
}
本文深入探讨数塔问题的解决方案,通过对比正序与倒序的处理方式,强调倒序方法的便利性与效率。利用动态规划算法优化计算过程,通过实例代码演示如何在原有数组上进行操作,实现简洁高效的求解过程。
2296

被折叠的 条评论
为什么被折叠?



