题解:
此题是一道比较简单的一道动态规划题目
设状态转移方程时容易想到的是 d[i,j] = 从最下面一格走到(i,j)的最佳值,但这样定义显然行不通,因为“最佳值”定义得太抽象,没办法描述。
所以应该定义为:d[i,j,k] = 从最下面一格走到(i,j)经过一系列加减拿到k可不可行。
但是此题的方程比较繁琐,要分两种情况,这里不细说了,大家可以在代码的第70-90行去看。
在做这道题的时候我遇到了一个问题,就是ready(0函数计算所有和的值的时候,在第40行。
一开始j没有初始化我就在使用,其实是一个笔误,我本来准备写1的。在本机上完全可以测试通过,但交上题库总是内存越界,最上面的check我就是写来检查越界的。遗憾的是check没有检查到任何错误,
因为在我的编译器上j被初始化了…………最后我把程序一小段一小段的交到题库上才发现是这里错了,调了接近一个小时…………orz
代码:
#define MAXN 35
#define MAXL 6010
#define ADD 3005
#define dp(i,j,k) d[(i)][(j)][(k)+ADD]
#define check if(i>=MAXN+MAXN || i<0 || j<0 || j>=MAXN || k+ADD<0 || k+ADD>=MAXL)throw "add error"
#include
#include
#include
using namespace std;
int d[MAXN+MAXN][MAXN][MAXL];
int a[MAXN+MAXN][MAXN];
int N;
int tot;
void input()
{
int i,j;
scanf("%d",&N);
for(i=1;i<=N;i++)
for(j=1;j<=i;j++)
scanf("%d",&a[i][j]);
for(i=N-1;i>0;i--)
for(j=1;j<=i;j++)
scanf("%d",&a[N+N-i][j]);
}
void ready()
{
int i,j,max,k=0;
memset(d,0,sizeof(d));
dp(N+N-1,1,a[N+N-1][1]) = 1;
tot = 0;
for(i=1;i<=N;i++)
{
max = a[i][1]; //开始写的max = a[i][j]; 教训啊教训
for(j=1;j<=i;j++)
{
check;
if(a[i][j]>max)max = a[i][j];
}
tot += max;
}
for(i=N-1;i>0;i--)
{
max = a[N+N-i][1];
for(j=1;j<=i;j++)
{
check;
if(a[N+N-i][j]>max)max = a[N+N-i][j];
}
tot += max;
}
}
void work()
{
int i,j,k;
for(i