面:
《snow halation》是μ’s的第二张单曲,其歌曲第二段伴奏结束后主唱穗乃果唱出“届けて”的同时,全场应援棒瞬间从白色转换成橙色。由于高度的整齐和效果的震撼,被称为“橙色的奇迹”,这也是“如果奇迹有颜色,那么一定是XX色”的最早来源。
现在,到了你来应援的时候了!
使用不同的应援形式有不同的效果(如里打、里跳、快挥、前挥、GT警报……),比如通常会GT警报后接着做里跳,这样能够让人更加沉迷到演唱会的气氛中。
经过精密的计算,我们终于得到了不同的应援形式连着对活跃气氛的贡献值(增加气氛的活跃值)。
现在给你一首歌的call表(记录应该如何应援),里面有一部分是0(代表这个动作可以自己随意选择),另一部分是非0整数,表示这个时候有规定的动作要做。
求这首歌能达到的最大气氛活跃值。
初始的气氛活跃值为0,第一个应援动作对气氛无影响。
Input
第1行:组数T(非负整数,1<=T<=10)
第2行:应援动作数n,call表长度m(非负整数,0<=n,m<=100)
第3~3+n行:每行n个整数,表示在第i个动作后接j的气氛贡献值,Wi,j表示当前行第j个。(|Wi,j|<=100)
第4+n行:m个非负整数a[i],表示call表内容。(0<=a[i]<=n)
……
Output
一行,一个整数,表示能达到的最大气氛活跃值。
Sample Input
2
3 5
83 86 77
15 93 35
86 92 49
3 3 3 1 2
5 10
36 11 68 67 29
82 30 62 23 67
35 29 2 22 58
69 67 93 56 11
42 29 73 21 19
0 0 5 0 4 0 0 0 4 0
Sample Output
270
625
大致思路:
一个思路比较明确的DP
DP [ i ] [ j ]
代表第i个动作是j时现在的最大应援值
那么现在可以把所有情况分成4种:
1.前一个动作已知:
(1)现在动作已知:值为固定值,无法选择
(2)现在动作未知:把所有可能的动作扫一遍 有转移方程:dp[i][j]=dp[i-1][cmd[i-1]]+mp[cmd[i-1]][j]
2.前一个动作未知
(1)现在动作已知:把前一个可能的动作扫一遍
(2)现在动作未知,把所有可能的对应关系全部扫一遍
trick点:
应援值有可能为负,最后答案也应该为负值。所以要初始化为-INF
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=110; 4 const int INF=1e6+7; 5 int mp[maxn][maxn]; 6 int cmd[maxn]; 7 int dp[maxn][maxn]; 8 int main() 9 { 10 ios::sync_with_stdio(false); 11 //freopen("in.txt","r",stdin); 12 int t,n,m,ans=0,dx; 13 cin>>t; 14 while(t--) 15 { 16 ans=-INF; 17 cin>>n>>m; 18 memset(mp,-INF,sizeof(mp)); 19 memset(dp,0,sizeof(dp)); 20 for(int i=1;i<=n;++i) 21 for(int j=1;j<=n;++j) 22 cin>>mp[i][j]; 23 for(int i=1;i<=m;++i) 24 cin>>cmd[i]; 25 for(int i=2;i<=m;++i){ 26 if(cmd[i-1]){ 27 if(cmd[i]) 28 dp[i][cmd[i]]=dp[i-1][cmd[i-1]]+mp[cmd[i-1]][cmd[i]]; 29 else{ 30 for(int j=1;j<=n;++j) 31 dp[i][j]=dp[i-1][cmd[i-1]]+mp[cmd[i-1]][j]; 32 } 33 }else{ 34 if(cmd[i]){ 35 dx=-INF; 36 for(int j=1;j<=n;++j) 37 dx=max(dx,dp[i-1][j]+mp[j][cmd[i]]); 38 dp[i][cmd[i]]+=dx; 39 } 40 else 41 for(int j=1;j<=n;++j){ 42 dx=-INF; 43 for(int k=1;k<=n;++k) 44 dx=max(dx,dp[i-1][k]+mp[k][j]); 45 dp[i][j]+=dx; 46 } 47 } 48 } 49 if(cmd[m]) 50 ans=dp[m][cmd[m]]; 51 else 52 for(int i=1;i<=n;++i) 53 ans=max(dp[m][i],ans); 54 cout<<ans<<endl; 55 } 56 return 0; 57 }