• HDU 5074 Hatsune Miku(DP)


    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5074

    题目大意:给定一个长度为n的序列c[i],该序列为一个乐谱。我们的任务是要给这个序列补上音符。c[i]的数值有两种情况:-1、不是-1。不是-1的这个位置的音符已经确定,不能再更改。是-1的这个位置音符可以任意选择。可以选择的音符有m种,编号为1-m。

                 当乐谱序列完成后,会有一个得分产生(即这乐谱的优美程度)。得分为score(c[1],c[2])+score(c[2],c[3])+...+score(c[n-1],c[n])。其中score[i][j]在题中已经给出。我们的任务是要把这个得分总和最大化。

    思路:显然是DP。由于我之前回顾了区间DP,因而……先想到了区间DP。但是这样显然不行。从DP的无后效性考虑,我大概想到了方法。。

            设f[i][j]为序列c[1]到c[i],并且c[i]=j时可以得到的最大得分。则可分4种情况讨论:

            1、c[i - 1] !=-1, c[i] != -1.这是最简单的情况,定死的。直接算即可。

        2、c[i - 1] == -1, c[i] != -1.此时只要对f[i - 1][j]进行枚举更新即可。

            3、c[i - 1] != -1,c[i] == -1.这种情况对f[i][j]进行枚举,从f[i - 1][c[i - 1]]更新即可。

            4、c[i - 1] == -1,c[i] != -1.该情况的状态转移方程为f[i][j] = max(f[i - 1][k] + score[k][j]).

       时间复杂度为O(NM^2)

       代码送上(代码中的a[i][j]即为这里的score[i][j])

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <functional>
     6 
     7 using namespace std;
     8 
     9 #define REP(i,n)        for(int i(0); i <  (n); ++i)
    10 #define rep(i,a,b)        for(int i(a); i <= (b); ++i)
    11 #define INF    1 << 30
    12 
    13 
    14 const int Q    =    1000        +    10;
    15 int f[Q][Q], a[Q][Q];
    16 int c[Q];
    17 int n, m;
    18 int T;
    19 
    20 int main(){
    21 
    22     scanf("%d", &T);
    23     REP(Case, T){
    24         memset(f, 0, sizeof f); memset(a, 0, sizeof a); memset(c, 0, sizeof c);
    25         scanf("%d%d", &n, &m);
    26         rep(i, 1, m) rep(j, 1, m) scanf("%d", &a[i][j]);
    27         rep(i, 1, n) scanf("%d", c + i);
    28         rep(i, 1, n) f[1][i] = 0;
    29         rep(i, 2, n){
    30             if (c[i] != -1 && c[i - 1] != -1) f[i][c[i]] = f[i - 1][c[i - 1]] + a[c[i - 1]][c[i]];
    31             if (c[i] != -1 && c[i - 1] == -1) rep(j, 1, m) f[i][c[i]] = max(f[i][c[i]], f[i - 1][j] + a[j][c[i]]);
    32             if (c[i] == -1 && c[i - 1] != -1) rep(j, 1, m) f[i][j] = f[i - 1][c[i - 1]] + a[c[i - 1]][j];
    33             if (c[i] == -1 && c[i - 1] == -1) rep(j, 1, m) rep(k, 1, m) f[i][j] = max(f[i][j], f[i - 1][k] + a[k][j]);
    34         }
    35         int ans = 0;
    36         if (c[n] == -1) rep(i, 1, m) ans = max(ans, f[n][i]); else ans = f[n][c[n]];
    37         printf("%d
    ", ans);
    38     }
    39     
    40     
    41     return 0;
    42     
    43 }
  • 相关阅读:
    springboot+fegin实现负载均衡
    springcloud实现微服务服务注册、负载均衡
    spring boot服务状态监控+shell远程连接服务
    微服务基础概念及相关技术组件
    集群分布式基础概念及了解
    http第一章-telnet测试
    spring整合netty

    springMVC+spring+JPA配置文件
    CAN信号值解析
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/5917749.html
Copyright © 2020-2023  润新知