比较水的DP。
题意是用m个不同音符创作含n个音符的音乐:a1, a2,a3.......an。要求max (sore(a1,a2)+sore(a2,a3)+...+sore(an-1, an))。
用dp[i][j]表示第i个音符使用j的最大价值,max (a[n][k] | 1<=k<=m)就是答案。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
#define maxn 111
#define INF 111111111
int dp[maxn][maxn];
int n, m;
int mp[maxn][maxn];
int a[maxn];
int main () {
//freopen ("data.txt", "r", stdin);
int t;
cin >>t;
while (t--) {
cin >> n >> m;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= m; j++)
cin >> mp[i][j];
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
dp[i][j] = -INF;
if (a[1] == -1) {
for (int i = 1; i <= m; i++)
dp[1][i] = 0;
}
else dp[1][a[1]] = 0;
for (int i = 2; i <= n; i++) {
if (a[i] != -1) {
for (int j = 1; j <= m; j++)
dp[i][a[i]] = max (dp[i][a[i]], dp[i-1][j]+mp[j][a[i]]);
}
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]+mp[k][j]);
}
}
}
int ans = -1;
for (int i = 1; i <= m; i++)
ans = max (ans, dp[n][i]);
cout << ans << endl;
}
return 0;
}