http://acm.hdu.edu.cn/showproblem.php?pid=2571
题意:求出从从(1,1)走到(n,m)的最大值!并且必须按要求走!!
另外一种就是用搜索做!求出最大的值!
状态方程:sum[i][j]=max{sum[i-1][j],sum[i][k]}+v[i][j];其中1<=k<=j-1,且k是j的因子。
具体见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int dp[25][1005];
int val[25][1005];
int main()
{
int i,j,k,t,n,m;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
scanf("%d",&val[i][j]);
dp[i][j]=-20000;//注意初始化!!
}
}
// memset(dp,-20000,sizeof(dp));
dp[1][1]=val[1][1];
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(i+1<=n)
dp[i+1][j]=max(dp[i+1][j],dp[i][j]+val[i+1][j]);//求出向右走一步的最大值!
if(j!=1)
{
if(j+1<=m)
dp[i][j+1]=max(dp[i][j+1],dp[i][j]+val[i][j+1]);//求出向下走一步的最大值!
}
k=2;//以下为求出走到该行的列数是当前所在列数倍数的格子的最大值!!
while(k*j<=m)//这里要注意while与if的用法(if 只要条件为真就执行(且只执行一次,即执行到{}内最后一行就不执行了。
//while 只要条件为真就一直循环执,直到条件为假,即执行到{}内最后一行还会返回(fahr<=upper)做判断,如果条件还是真的则再执行{}里的内容
{
dp[i][j*k]=max(dp[i][j]+val[i][j*k],dp[i][j*k]);
k++;
}
}
}
printf("%d\n",dp[n][m]);
}
return 0;
}