hdu5074 Hatsune Miku

题意:有一个m*m的矩阵,每个位置都有一个值,然后给你一个序列,-1的位置可以替换,然后求出序列的最大值

思路:问题的关键在于dp状态的定义,(训练的时候没想出来,以为贪心,但不知道怎么贪,dp也不知道怎么转移,我竟然还想到用最短路做,可能脑子坏掉了,还是太菜了)

定义dp【i】【j】中i代表目前用了几个数,就是进行到a【i】的第几个了,j代表最后一个数用的是几,然后分情况讨论a[i],a[i-1]与0的关系.最后扫一下dp【n】【i】的最大值

得出结果

下面是代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn=105;
 6 int dp[maxn][maxn];
 7 int mp[maxn][maxn];
 8 int a[maxn];
 9 
10 int main()
11 {
12     int t;
13     scanf("%d",&t);
14     while(t--){
15         int n,m;
16         scanf("%d %d",&n,&m);
17         for(int i=1;i<=m;i++){
18             for(int j=1;j<=m;j++){
19                 scanf("%d",&mp[i][j]);
20             }
21         }
22         for(int i=1;i<=n;i++)
23             scanf("%d",&a[i]);
24         memset(dp,0,sizeof(dp));
25         for(int i=2;i<=n;i++){
26             if(a[i]>0&&a[i-1]>0){
27                 dp[i][a[i]]=dp[i-1][a[i-1]]+mp[a[i-1]][a[i]];
28             }
29             else if(a[i-1]<0&&a[i]>0){
30                 for(int k=1;k<=m;k++){
31                     dp[i][a[i]]=max(dp[i][a[i]],dp[i-1][k]+mp[k][a[i]]);
32                 }
33             }
34             else if(a[i-1]<0&&a[i]<0){
35                 for(int j=1;j<=m;j++){
36                     for(int k=1;k<=m;k++){
37                         dp[i][j]=max(dp[i][j],dp[i-1][k]+mp[k][j]);
38                     }
39                 }
40             }
41             else if(a[i-1]>0&&a[i]<0){
42                 for(int k=1;k<=m;k++){
43                     dp[i][k]=max(dp[i][k],dp[i-1][a[i-1]]+mp[a[i-1]][k]);
44                 }
45             }
46         }
47         int cnt=0;
48         for(int i=1;i<=m;i++)
49             cnt=max(cnt,dp[n][i]);
50         printf("%d\n",cnt);
51     }
52     return 0;
53 }

 

posted @ 2017-07-24 21:40  啦啦啦天啦噜  阅读(186)  评论(0编辑  收藏  举报