hdu 5074 Hatsune Miku

本文介绍了一道关于使用动态规划(DP)算法来解决特定问题的题目,该问题涉及构建由不同音符组成的串,并通过一个m*m的矩阵评估其美丽值。通过有效的DP策略,文章详细阐述了如何在某些音符固定而另一些可以自由选择的情况下,找到最优解以最大化整个串的美丽值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        题意:共有m种note,用n个node组成一个串,在这n个note中,有些是指定的,有些是可以任意改变的。你需要使串的beautifulness值最大。beautifulness值是由相邻的note种类对应的一个m*m矩阵中的值得到的。

        思路:dp。dp(i,j)表示第i个note选择j类型得到的beautifulness最大值。


#include <iostream>       
#include <stdio.h>       
#include <cmath>       
#include <algorithm>       
#include <iomanip>       
#include <cstdlib>       
#include <string>       
#include <string.h>       
#include <vector>       
#include <queue>       
#include <stack>       
#include <map>     
#include <set>     
#include <ctype.h>       
#include <sstream>   
#define INF 1000000000   
#define ll long long   
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
     
using namespace std;


int mp[110][110];
int dp[110][110];
int a[110];

int main(){
    int t;
    cin>>t;
    while(t--){
        memset(dp,0,sizeof(dp));
        
        int n,m;
        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=2;i<=n;i++){
            for(int j=1;j<=m;j++){
                
                if(a[i-1]>0){
                    if(a[i]>0){
                        dp[i][a[i]]=dp[i-1][a[i-1]]+mp[a[i-1]][a[i]];
                    }else{
                        dp[i][j]=dp[i-1][a[i-1]]+mp[a[i-1]][j];
                    }
                }else{
                    if(a[i]>0){
                        if(j!=a[i])continue;
                        for(int k=1;k<=m;k++){
                            dp[i][a[i]]=max(dp[i][a[i]],dp[i-1][k]+mp[k][a[i]]);
                        }
                    }else{
                        for(int k=1;k<=m;k++){
                            dp[i][j]=max(dp[i][j],dp[i-1][k]+mp[k][j]);
                        }
                    }
                }
            }
        }
        int ans=0;
        for(int i=1;i<=m;i++){
            ans=max(ans,dp[n][i]);
        }
        cout<<ans<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值