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;
}

 

posted @ 2015-09-01 14:28  dominating大树置林  Views(125)  Comments(0)    收藏  举报