Uva Hatsune Miku(dp)
题意:给定一个m*m的矩阵,每个格子有一个值,给出n个数,求以相邻两数为横纵坐标对应的矩阵值之和的最大值;当坐标值为负数时,填上一个数;
思路:dp[i][j]=max(dp[i][j],dp[i-1][k]+mm[k][j]);
dp[i][j]表示当前取i个值,第i个值的第二位坐标为j;递推求最优解;
#include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> using namespace std; #define inf 0x3f3f3f3f int t,n,m; int mm[55][55]; int num[105]; int dp[105][105]; int main(){ int i,j,k; scanf("%d",&t); while(t--){ memset(mm,0,sizeof(mm)); scanf("%d%d",&n,&m); for(i=1;i<=m;i++){ for(j=1;j<=m;j++){ scanf("%d",&mm[i][j]); } } for(i=1;i<=n;i++) scanf("%d",&num[i]); for(i=0;i<105;i++){ for(j=0;j<105;j++){ dp[i][j]=-inf; } } if(num[1]>0){ dp[1][num[1]]=0; } else{ for(i=1;i<=m;i++){ dp[1][i]=0; } } for(i=2;i<=n;i++){ if(num[i]>0){ for(j=1;j<=m;j++){ dp[i][num[i]]=max(dp[i][num[i]],dp[i-1][j]+mm[j][num[i]]); } } else{ for(j=1;j<=m;j++){ for(k=1;k<=m;k++){ dp[i][j]=max(dp[i][j],dp[i-1][k]+mm[k][j]); } } } } int ans=0; for(i=1;i<=m;i++){ ans=max(ans,dp[n][i]); } printf("%d\n",ans); } return 0; }

浙公网安备 33010602011771号