• AHU-727 美妙音乐 【DP】


    Description
    西瓜和Roll组团去冒险,他们打开了隐藏的密门,发现了矮人矿洞的秘密。那是多年前由矮人王亲自下令改建的密室,据说只有最美妙的音乐可以指引他们找到宝藏。
    一首音乐是最美妙的,当且仅当每两个相邻音符的和谐度之和最大。西瓜发现了一张矮人公认的最美和谐度表harmony。西瓜发现,他可以使用m种音符构造音乐,最终构成的音乐共包含n个音符。西瓜兴致勃勃地谱出了最美妙的音乐,不幸的是,在矮人矿洞Roll发现矮人们的音乐有固定的模板,他们应当按照矮人们的模板再谱出一首曲子。由于西瓜的谱曲天赋有限,一天只能谱写一首曲子,他们想尽快进入那个矿洞,只有找你来帮助他们。
     
    Input
    输入数据第一行,包含一个整数T,为数据组数(1≤T≤10)。
    对于每组数据,第一行包含两个整数n和m,(1≤n≤100,1≤m≤50)。
    接下来m行,每行包括m个用空格隔开的整数,第i行第j列表示harmony(i,j)(0≤harmony(i,j) ≤100)。
    接下来一行包含n个用空格隔开的整数ai(-1≤ai≤m且ai≠0),ai为-1时代表你可以随意指定音符,ai>0时你不能改变音符。
    Output
    对于每组数据,输出包括两个用空格隔开的整数x,y。x为在矮人模板下最大的和谐度,y为没有模板限制时最大的和谐度。
    Sample Input
    1
    42 2
    31 96
    18 96
    2 -1 -1 2 -1 -1 -1 -1 2 -1 -1 1 -1 1 -1 -1 -1 2 1 -1 -1 -1 -1 1 2 2 -1 -1 1 2 2 -1 1 2 -1 2 -1 2 1 2 -1 -1
    Sample Output
    3390 3936
    
    

    思路:

    比较容易想到是一道DP,用f(i,j)代表到第i个音符时选择音符j的最大和谐度,k代表第i-1个音符,则不按模板时,有转移方程:
            f(i,j) = max1<=k<=m(f(i,j), f(i-1,k)+h(k,j))
    按照模板时,只要ai>0时将j!=ai时的f(i,j)全部赋值为-inf再按上式递推就行


    Code:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define INF 0x3f3f3f3f
     4 int f[105][55], g[105][55], h[55][55], a[105];
     5 
     6 int main() {
     7     ios::sync_with_stdio(false);
     8     int T, n, m;
     9     cin >> T;
    10     while (T--) {
    11         memset(f, 0, sizeof(f));
    12         memset(g, 0, sizeof(g));
    13         cin >> n >> m;
    14         for (int i = 1; i <= m; ++i)
    15             for (int j = 1; j <= m; ++j)
    16                 cin >> h[i][j];
    17         for (int i = 1; i <= n; ++i) cin >> a[i];
    18         int ans1 = 0, ans2 = 0;
    19         for (int i = 2; i <= n; ++i) 
    20             for (int j = 1; j <= m; ++j)
    21                 for (int k = 1; k <= m; ++k) {
    22                     f[i][j] = max(f[i][j], f[i-1][k] + h[k][j]);
    23                     ans2 = max(ans2, f[i][j]);
    24                 }
    25         if (a[1] > 0)
    26             for (int i = 1; i <= m; ++i)
    27                 if (a[1] != i) g[1][i] = -INF;
    28         for (int i = 2; i <= n; ++i) {
    29             if (a[i] > 0) {
    30                 for (int j = 1; j <= m; ++j)
    31                     if (j != a[i]) g[i][j] = -INF;
    32                     else for (int k = 1; k <= m; ++k)
    33                         g[i][j] = max(g[i][j], g[i-1][k] + h[k][j]);
    34             }
    35             else {
    36                 for (int j = 1; j <= m; ++j)
    37                     for (int k = 1; k <= m; ++k)
    38                         g[i][j] = max(g[i][j], g[i-1][k] + h[k][j]);
    39             }
    40         }
    41         for (int i = 1; i <= m; ++i) ans1 = max(ans1, g[n][i]);
    42         cout << ans1 << " " << ans2 << endl;
    43     }
    44 
    45     return 0;
    46 }
  • 相关阅读:
    win7下DS、KS、ASIO、WASAPI输出比较
    什么叫时钟漂移(Wander)?时钟漂移与时钟抖动(jitter)的区别
    常见编译/链接错误及其解决办法
    理解 Visual C++ 应用程序的依赖项(msdn)
    初识windows语音采集和回放
    依赖关系、概况关系、关联关系等概念
    VS2010工程转VS2005工程的方法
    speech codec (G.711, G.723, G.726, G.729, iLBC)
    【转】深入剖析iLBC的丢包补偿技术(PLC)
    CSS优先级问题
  • 原文地址:https://www.cnblogs.com/robin1998/p/6601567.html
Copyright © 2020-2023  润新知