从上走到底部,数塔问题。
用数塔思想,只是走的方法略微有点差异,下一步可以是(x+1,y),(x,y+1)或者(x,y*k) 其中k>1。
数塔方法,从底部往上求,先求最后一行的,然后往前推,为了一定要走大魔王那一格,先把大魔王那格值变大,原题幸运值小于100,可以搞个200什么的,
最后减去200加上他原来的值就是所求答案。
代码:
#include<stdio.h>
#include<string.h>
int dp[30][1010];
int main()
{
int n,m;
int i,j,T,temp,maxtemp,k,t;
scanf("%d",&T);
while(T--)
{
memset(dp,0,sizeof(dp));
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&dp[i][j]);
temp=dp[n][m];
dp[n][m]=150;
for(i=m-1;i>=1;i--)
{
maxtemp=dp[n][i+1];
k=2;
j=k*i;
while(j<=m)
{
if(maxtemp<dp[n][j]) maxtemp=dp[n][j];
k++;
j=k*i;
}
dp[n][i]+=maxtemp;
}
for(i=n-1;i>=1;i--)
{
for(j=m;j>=1;j--)
{
if(j==m) dp[i][j]+=dp[i+1][j];
else
{
maxtemp=dp[i+1][j];
if(maxtemp<dp[i][j+1]) maxtemp=dp[i][j+1];
k=2;
t=k*j;
while(t<=m)
{
if(dp[i][t]>maxtemp) maxtemp=dp[i][t];
k++;
t=k*j;
}
dp[i][j]+=maxtemp;
}
}
}
/* for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
printf("%d ",dp[i][j]);
}
printf("\n");
}*/
printf("%d\n",dp[1][1]-dp[n][m]+temp);
}
return 0;
}