HDU-5074

Hatsune Miku

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 931    Accepted Submission(s): 651

Problem Description

Hatsune Miku is a popular virtual singer. It is very popular in both Japan and China. Basically it is a computer software that allows you to compose a song on your own using the vocal package.

Today you want to compose a song, which is just a sequence of notes. There are only m different notes provided in the package. And you want to make a song with n notes.


Also, you know that there is a system to evaluate the beautifulness of a song. For each two consecutive notes a and b, if b comes after a, then the beautifulness for these two notes is evaluated as score(a, b).

So the total beautifulness for a song consisting of notes a1, a2, . . . , an, is simply the sum of score(ai, ai+1) for 1 ≤ i ≤ n - 1.

Now, you find that at some positions, the notes have to be some specific ones, but at other positions you can decide what notes to use. You want to maximize your song’s beautifulness. What is the maximum beautifulness you can achieve?

Input

The first line contains an integer T (T ≤ 10), denoting the number of the test cases.

For each test case, the first line contains two integers n(1 ≤ n ≤ 100) and m(1 ≤ m ≤ 50) as mentioned above. Then m lines follow, each of them consisting of m space-separated integers, the j-th integer in the i-th line for score(i, j)( 0 ≤ score(i, j) ≤ 100). The next line contains n integers, a1, a2, . . . , an (-1 ≤ ai ≤ m, ai ≠ 0), where positive integers stand for the notes you cannot change, while negative integers are what you can replace with arbitrary notes. The notes are named from 1 to m.

Output

For each test case, output the answer in one line.

Sample Input

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

Sample Output

270

625

Source

2014 Asia AnShan Regional Contest

/**
    题意:m种点,一个长度为n的串,若串中的数为-1  则为待定,否则为这点
            求这个串的最大价值,
    做法:dp
            分为四种情况,如果当前点是未知
                                前一个点已知
                                前一个点未知
                          如果当前点已知
                                  前一个点已知
                                  前一个点未知
            情况很少  很容易枚举
    ============================================================
                        dp是硬伤
    ============================================================
**/
#include <iostream>
#include <algorithm>
#include <string.h>
#include <cmath>
#include <stdio.h>
#include <queue>
#define maxn 110
using namespace std;
int score[maxn][maxn];
int note[maxn];
int dp[maxn][maxn];
int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        int n, m;
        scanf("%d %d", &n, &m);
        for(int i = 1; i <= m; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                scanf("%d", &score[i][j]);
            }
        }
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &note[i]);
        }
        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]);
                        }
                    }
                }
            }
        }
        int  sum = -1;
        if(note[n] > 0) {
            sum = dp[n][note[n]];
        }
        else
        {
            for(int i = 1; i <= m; i++)
            {
                sum = max(sum, dp[n][i]);
            }
        }
        printf("%d\n", sum);
    }
    return 0;
}

时间: 2024-10-12 00:36:11

HDU-5074的相关文章

hdu 5074 DP 2014鞍山现场赛题

hdu 5074 http://acm.hdu.edu.cn/showproblem.php?pid=5074 挺水的DP,注意依a[i-1]和a[i]的正负区分状态转移,然后O(n^3)即可轻易解决,我DP挺弱的也能过,貌似也就CF C题水平 //#pragma comment(linker, "/STACK:102400000,102400000") #include <cstdio> #include <cstring> #include <algo

HDU 5074 Hatsune Miku (线性dp)

Hatsune Miku Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 654    Accepted Submission(s): 471 Problem Description Hatsune Miku is a popular virtual singer. It is very popular in both Japan

[HDU 5074] Hatsune Miku (动态规划)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5074 题目大意是给你m个note,n个数,得分是v[a[i]][a[i+1]]的总和,如果说a[i]是负数的话代表可以放人一个note,否则就只能放他给的note号. 问:最大的得分是多少? 我先写了记忆化搜索函数 dp(i,j)代表到第i个位置,放标号为j的note 那么 如果说a[i+1]<0,那么dp(i,j) = max( dp(i,j) , dp(i+1,k)+v[j][k] ); 否则d

HDU 5074 Hatsune Miku

Hatsune Miku Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on HDU. Original ID: 507464-bit integer IO format: %I64d      Java class name: Main Hatsune Miku is a popular virtual singer. It is very popular in both Japan and Chin

HDU 5074 Hatsune Miku(2014鞍山赛区现场赛E题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5074 解题报告:给出一个长度为n的序列,例如a1,a2,a3,a4......an,然后这个序列的美丽值就是socre[a1][a2] + socre[a2][a3] + ..... socre[an-1][an],但是这个序列里面并不是所有的数都是确定的,输入包含一些大于0的数和一些-1,-1表示这个数可以任意,但是要在m的范围内,给出socre[i][j],求这个序列最大的美丽值. 一个二维dp

hdu 5074 相邻数和最大dp

http://acm.hdu.edu.cn/showproblem.php?pid=5074 给定一个序列 有些位数未知,给你所有两个数连续所得到的能量,问你怎么安排数字使得总能量最大 二维dp,dp[i][j]表示第i位放音符j 分类讨论即可 #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <string> #include &l

hdu 5074 Hatsune Miku(2014 鞍山现场赛)

Hatsune Miku Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 17    Accepted Submission(s): 14 Problem Description Hatsune Miku is a popular virtual singer. It is very popular in both Japan an

HDU 5074 Hatsune Miku(简单二维dp)

题目大意:给你一些音符之间的联系,给你一个串,让你求出这个串的最大值.-1的时候可以任意替代,其他情况必须为序列上的数. 解题思路:简单二维dp,分情况处理就可以了啊. Hatsune Miku Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 637    Accepted Submission(s): 458 Problem De

HDU 5074 Hatsune Miku(14鞍山区域赛 E)DP

题意:给定一个序列 有些位数未知,给你如果两个数连续所得到的能量,问你怎么安排数字使得总能量最大 解题思路:dp,只与上一个字母有关. 解题代码: 1 // File Name: e.cpp 2 // Author: darkdream 3 // Created Time: 2014年10月22日 星期三 12时16分10秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set&g

HDU 5074 Luck Competition (暴力,概率)

题意:有 n 个人参加比赛,给出n-1个人的成绩,然后要选出一个幸运的人,先把所有的分数求平均数,然后再*2/3,那个不大于这个数,且最接近的数,就是最幸运的, 让你设置最后一个人的分,使他是最幸运的. 析:题目说了,最多是100,那么这么少,完全可以暴力啊,然后不断更新最大概率. 代码如下: #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include &l