2 5 3 83 86 77 15 93 35 86 92 49 3 3 3 1 2 10 5 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 -1 -1 5 -1 4 -1 -1 -1 4 -1
270 625
题意为有m种音符,编号1到m,我们要用这m种音符来创造一首带有n个音符的曲子(当然,一种音符可以用多次),假设有两个连续的音符 i ,j ,那么定义score(i,j)为这两个音符的得分,题目中预先给出所有的score(i,j) 1<=i,j<=m, 那么我们创造出的n个音符的曲子的得分为 score( note[i] , note[i+1] ) + score (note[i+1] ,note[i+2) +......score(note[n-1],note[n]) , i从1开始。 note [i] 代表n个音符的曲子中第i个音符是第几种音符, 1<=note[i]<=m, 比如 note[i]=3,就表示n个音符中第i个位置用的是第3种音符(一共有m种),预先给出 这n个音符,note[1] 到note[n] ,其中note[ i] 或者等于-1 ,或者 大于等于1小于等于m,对于后者,该位置的音符不能改变,对于前者,该位置可以换成任意的音符j(1<=j<=m), 问 这n个音符所获得的最大得分是多少。
虽然是简单Dp,但还是Dp题做的少,不敏感,一开始还用暴搜来做了。。
定义dp [i ][j],为前i个音符且第i个音符为第j种音符所获得的最大得分。
分情况讨论:
当note[i] >0 (i>=2)时:
当note[i-1]>0时: dp[i][note[i]]=dp[i-1][note[i-1]]+score[note[i-1]][note[i]];
当note[i-1]<0时: dp[i][note[i]]=max(dp[i][note[i]],dp[i-1][j]+score[j][note[i]]); 1<=j<=m, 枚举第i-1个音符是第几种音符
当note[i]<0 (i>=2)时:
当note[i-1]>0时:dp[i][j]=max(dp[i][j],dp[i-1][note[i-1]]+score[note[i-1]][j]); 1<=j<=m, 枚举第i个音符是第几种音符
当note[i-1]<0时:dp[i][j]=max(dp[i][j],dp[i-1][k]+score[k][j]); 1<=j,k<=m, 枚举第i个音符和第i-1个音符是第几种音符
代码:
#include <iostream> #include <string.h> #include <algorithm> using namespace std; int n,m; int score[52][52]; int dp[102][52];//dp[i][j]表示为前i个音符,以第j种音符结尾所获得的最大分数 int note[102]; int ans; void DP() { memset(dp,0,sizeof(dp)); for(int i=2;i<=n;i++) { if(note[i]>0) { if(note[i-1]>0) dp[i][note[i]]=dp[i-1][note[i-1]]+score[note[i-1]][note[i]]; else { for(int j=1;j<=m;j++) dp[i][note[i]]=max(dp[i][note[i]],dp[i-1][j]+score[j][note[i]]); } } else { if(note[i-1]>0) { for(int j=1;j<=m;j++) dp[i][j]=max(dp[i][j],dp[i-1][note[i-1]]+score[note[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]+score[k][j]); } } } ans=-1; if(note[n]>0) ans=dp[n][note[n]]; else { for(int j=1;j<=m;j++) { if(ans<dp[n][j]) ans=dp[n][j]; } } } int main() { int t; cin>>t; while(t--) { cin>>n>>m; for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) cin>>score[i][j]; for(int i=1;i<=n;i++) cin>>note[i]; DP(); cout<<ans<<endl; } return 0; }
[ACM] HDU 5074 Hatsune Miku (简单DP)
原文地址:http://blog.csdn.net/sr_19930829/article/details/40392311