hdu 5074 http://acm.hdu.edu.cn/showproblem.php?pid=5074
挺水的DP,注意依a[i-1]和a[i]的正负区分状态转移,然后O(n^3)即可轻易解决,我DP挺弱的也能过,貌似也就CF C题水平
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;
#define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout)
const ll ll_INF = ((ull)(-1))>>1;
const double EPS = 1e-8;
const double pi = acos(-1.0);
const ll INF = 1e18;
const int MAXN = 100+10;
int mat[MAXN][MAXN];
ll dp[MAXN][MAXN];
int a[MAXN];
int n,m;
ll solve()
{
for(int i=2;i<=n;i++)
{
if(a[i]>0)
{
if(a[i-1]>0)
dp[i][a[i]]=max(dp[i][a[i]],dp[i-1][a[i-1]]+mat[a[i-1]][a[i]]);
else
for(int k=1;k<=m;k++)
dp[i][a[i]]=max(dp[i][a[i]],dp[i-1][k]+mat[k][a[i]]);
}
else
{
if(a[i-1]>0)
{
for(int j=1;j<=m;j++)
dp[i][j]=max(dp[i][j],dp[i-1][a[i-1]] + mat[a[i-1]][j]);
}
else
{
for(int j=1;j<=m;j++)
{
for(int k=1;k<=m;k++)
dp[i][j]=max(dp[i][j],dp[i-1][k]+mat[k][j]);
}
}
}
}
ll ans=0LL;
for(int i=1;i<=m;i++)
ans=max(ans,dp[n][i]);
return ans;
}
int main()
{
//IN("hdu5074.txt");
int ncase;
scanf("%d",&ncase);
while(ncase--)
{
scanf("%d%d",&n,&m);
CL(mat,0);
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
scanf("%d",&mat[i][j]);
a[0]=0;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
CL(dp,0);
printf("%I64d\n",solve());
}
return 0;
}