本來(lái)不會(huì)的歧譬,在隊(duì)友細(xì)心指導(dǎo)下做出來(lái)了亡笑!開(kāi)心脸狸!
題目鏈接:
http://acm.hdu.edu.cn/showproblem.php?pid=2571
解題思路:
裸dp
先建個(gè)二維num存數(shù)據(jù)钳枕,
(我定義越往右下缴渊,輩分越小,即左上是爸爸鱼炒,右下是兒子)
二維dp存這個(gè)位置下的由父親過(guò)來(lái)的最大數(shù)值
根據(jù)“下一步可以是(x+1,y)衔沼,(x,y+1)或者(x,y*k) 其中k>1。 ”
先注意邊界處理dp為-inf昔瞧,01和10坐標(biāo)的dp取0指蚁,致使后面循環(huán)條件方便
雙層循環(huán)取相鄰最大的爸爸
即temp=max(dp[i-1][j]+num[i][j],dp[i][j-1]+num[i][j]);
再利用循環(huán)找左邊跳過(guò)來(lái)的因數(shù)爸爸
之后這倆(三)爸爸取最大值作為當(dāng)前未知的dp值
最后輸出終點(diǎn)位置的的dp值
AC代碼:
#include<bits/stdc++.h>
using namespace std;
int n,m,num[25][1005],dp[25][1005];
const int inf=99999999;
//num儲(chǔ)存當(dāng)前位置的數(shù)據(jù),dp存到達(dá)此位置時(shí)最高幸運(yùn)值
int main()
{
int c;
cin>>c;
while(c--)
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>num[i][j];
memset(dp,0,sizeof(dp));
int line=max(n,m);
for(int i=0;i<=n;i++) //邊界控制自晰,這樣后顧無(wú)憂(yōu)
dp[i][0]=-inf;
for(int j=0;j<=m;j++)
dp[0][j]=-inf;
dp[0][1]=0,dp[1][0]=0; //這個(gè)是為了后續(xù)num[1][1]不受邊界干擾
//下一步可以是(x+1,y)凝化,(x,y+1)或者(x,y*k) 其中k>1。
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int temp1=dp[i-1][j]+num[i][j]; //temp1:他的父親是上位
int temp2=dp[i][j-1]+num[i][j]; //temp2:他的父親是左鄰位
int MAX=max(temp1,temp2);
int temp3=-inf;
for(int tj=1;tj<j;tj++) //temp3:他的父親是左因數(shù)位
if(j%tj==0)
temp3=max(temp3,dp[i][tj]+num[i][j]);
dp[i][j]=max(MAX,temp3);
}
}
printf("%d\n",dp[n][m]);
}
return 0;
}