HDU 2296 Ring

Ring

Time Limit: 1000ms

Memory Limit: 32768KB

This problem will be judged on HDU. Original ID: 2296
64-bit integer IO format: %I64d      Java class name: Main

For the hope of a forever love, Steven is planning to send a ring to Jane with a romantic string engraved on. The string‘s length should not exceed N. The careful Steven knows Jane so deeply that he knows her favorite words, such as "love", "forever". Also, he knows the value of each word. The higher value a word has the more joy Jane will get when see it.
The weight of a word is defined as its appeared times in the romantic string multiply by its value, while the weight of the romantic string is defined as the sum of all words‘ weight. You should output the string making its weight maximal.

Input

The input consists of several test cases. The first line of input consists of an integer T, indicating the number of test cases. Each test case starts with a line consisting of two integers: N, M, indicating the string‘s length and the number of Jane‘s favorite words. Each of the following M lines consists of a favorite word Si. The last line of each test case consists of M integers, while the i-th number indicates the value of Si.
Technical Specification

1. T ≤ 15
2. 0 < N ≤ 50, 0 < M ≤ 100.
3. The length of each word is less than 11 and bigger than 0.
4. 1 ≤ Hi ≤ 100. 
5. All the words in the input are different.
6. All the words just consist of ‘a‘ - ‘z‘.

Output

For each test case, output the string to engrave on a single line.
If there‘s more than one possible answer, first output the shortest one. If there are still multiple solutions, output the smallest in lexicographically order.

The answer may be an empty string.

Sample Input

2
7 2
love
ever
5 5
5 1
ab
5

Sample Output

lovever
abab

Hint

Sample 1: weight(love) = 5, weight(ever) = 5, so weight(lovever) = 5 + 5 = 10 Sample 2: weight(ab) = 2 * 5 = 10, so weight(abab) = 10

Source

The 4th Baidu Cup final

解题:Trie 图 + 动态规划。由于需要字典序最小,所以从后面倒着dp

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 using PII = pair<int,int>;
 4 const int maxn = 510;
 5
 6 struct Trie{
 7     int ch[maxn][26],fail[maxn],cnt[maxn],tot;
 8     int dp[maxn][maxn];
 9     PII path[maxn][maxn];
10     int newnode(){
11         memset(ch[tot],0,sizeof ch[tot]);
12         fail[tot] = cnt[tot] = 0;
13         return tot++;
14     }
15     void init(){
16         tot = 0;
17         newnode();
18     }
19     void insert(char *str,int val,int rt = 0){
20         for(int i = 0; str[i]; ++i){
21             int &x = ch[rt][str[i]-‘a‘];
22             if(!x) x = newnode();
23             rt = x;
24         }
25         cnt[rt] += val;
26     }
27     void build(int rt = 0){
28         queue<int>q;
29         for(int i = 0; i < 26; ++i)
30             if(ch[rt][i]) q.push(ch[rt][i]);
31         while(!q.empty()){
32             rt = q.front();
33             q.pop();
34             cnt[rt] += cnt[fail[rt]];
35             for(int i = 0; i < 26; ++i){
36                 int &x = ch[rt][i],y = ch[fail[rt]][i];
37                 if(x){
38                     fail[x] = y;
39                     q.push(x);
40                 }else x = y;
41             }
42         }
43     }
44     void solve(int n){
45         memset(dp,0,sizeof dp);
46         for(int i = n; i; --i){
47             for(int j = 0; j < tot; ++j){
48                 for(int k = 0; k < 26; ++k){
49                     int x = ch[j][k],tmp = dp[i+1][x] + cnt[x];
50                     if(tmp > dp[i][j]){
51                         dp[i][j] = tmp;
52                         path[i][j] = PII(x,k);
53                     }
54                 }
55             }
56         }
57         int pos = n + 1,ans = 0,st = 0;
58         for(int i = n + 1; i; --i)
59             if(dp[i][0] > ans) ans = dp[pos = i][0];
60         for(int i = pos; i <= n; ++i){
61             printf("%c",path[i][st].second + ‘a‘);
62             st = path[i][st].first;
63         }
64         putchar(‘\n‘);
65     }
66 }ac;
67 char str[maxn][maxn];
68 int main(){
69     int kase,n,m,val;
70     scanf("%d",&kase);
71     while(kase--){
72         scanf("%d%d",&n,&m);
73         for(int i = 0; i < m; ++i)
74             scanf("%s",str[i]);
75         ac.init();
76         for(int i = 0; i < m; ++i){
77             scanf("%d",&val);
78             ac.insert(str[i],val);
79         }
80         ac.build();
81         ac.solve(n);
82     }
83     return 0;
84 }

时间: 2024-08-07 22:33:24

HDU 2296 Ring的相关文章

HDU 2296 Ring [AC自动机 DP 打印方案]

Ring Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3536 Accepted Submission(s): 1153 Problem Description For the hope of a forever love, Steven is planning to send a ring to Jane with a romantic

HDU 2296 Ring (AC自动机 + DP)

题目链接:Ring 解析:m个有价值的串,字符串s在字符串str中的价值 = s在str中出现的次数 × s的价值.问价值最大的长度为n的串是什么. 本题需要输出字典序最小的 在DP的时候开一个数组记录结果即可. AC代码: #include <algorithm> #include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace s

HDU 2296 Ring AC自动机 + DP

题意:给你n个模式串,每个模式串有一个得分,让你构造出一个长度为N之内且分数最高的文本串;输出字典序列最小的. 解题思路:  AC自动机 + DP , 不过要输出字典序列最小,多开一个 一个三维字符串来辅助二维DP(新思路) , DP[i][j] ,表示到i位置状态为j的最大得分. 解题代码: 1 // File Name: temp.cpp 2 // Author: darkdream 3 // Created Time: 2014年09月11日 星期四 15时18分4秒 4 5 #inclu

hdu 2296 aC自动机+dp(得到价值最大的字符串)

Ring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3180    Accepted Submission(s): 1033 Problem Description For the hope of a forever love, Steven is planning to send a ring to Jane with a rom

HDU 1016-Prime Ring Problem(DFS)

Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 27595    Accepted Submission(s): 12271 Problem Description A ring is compose of n circles as shown in diagram. Put natural num

HDU 1016Prime Ring Problem

http://acm.hdu.edu.cn/showproblem.php?pid=1016 题意:输入一个数,给出符合要求的素数环. 经典的dfs遍历. 1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 using namespace std; 5 6 int visited[25]; 7 int pos[25]; 8 int n, kase = 0; 9 10 int judge(int x)

HDU Prime Ring Problem (DFS+素数打表)

Problem Description A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each circle separately, and the sum of numbers in two adjacent circles should be a prime. Note: the number of first circle should always be 1

HDU 2296

很明显的DP状态了,设dp[i][j],设当前在状态点i,经过j步能得到的最大分值.也是从root直接扩展就可以了. 至于字符串,实在有点困难,开始想着记录路径,但后来发现路径从后往前回溯不一定是字典序最小,夭折...看别人的,发现直接就把字符串存下来,跪了,也对,毕竟才50个. 直接存字符串,比较,选最小,即可. #include <iostream> #include <cstdio> #include <cstring> #include <algorith

hdu Prime Ring Problem

简单的dfs,貌似这道题用暴力枚举就可以了,毕竟数据开的是比较小的. #include"iostream" #include"algorithm" #include"stdio.h" #include"string.h" #include"string" #include"vector" #include"cmath" #define mx 105 using nam