HDU 2296 Ring(AC自动机 + DP 记录方案)
2013-09-24 16:09
246 查看
题目链接:Click here~~
题意:
给 m 个带权值的串,构造一个长度为 n 的串,使总串的权值和最大,并输出字典序最小的方案。
解题思路:
令 dp[i][j] 表示长度为 i ,位于自动机节点 j 所能构成的最大权值。
状态和写法和上道题目类似,然后暴力记录方案。
题意:
给 m 个带权值的串,构造一个长度为 n 的串,使总串的权值和最大,并输出字典序最小的方案。
解题思路:
令 dp[i][j] 表示长度为 i ,位于自动机节点 j 所能构成的最大权值。
状态和写法和上道题目类似,然后暴力记录方案。
#include <queue> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define CLR(a,v) memset(a,v,sizeof(a)) namespace Trie { const int N = 1111; const int Size = 26; int top; struct Node{ Node *next[Size], *f; int ended_val; }node , *root; inline Node* new_node() { node[top].ended_val = 0; CLR(node[top].next,false); return &node[top++]; } void init() { top = 0; root = new_node(); } void insert(char *s,int val) { Node *u = root; for(int i=0;s[i];i++) { int id = s[i] - 'a'; if(u->next[id] == NULL) u->next[id] = new_node(); u = u->next[id]; } u->ended_val = val; } } namespace ACam { using namespace Trie; void get_fail() { queue<Node*> Q; for(int i=0;i<Size;i++) { Node *&ch = root->next[i]; if(!ch) ch = root; else { ch->f = root; Q.push(ch); } } while(!Q.empty()) { Node *cur = Q.front();Q.pop(); for(int i=0;i<Size;i++) { Node *&ch = cur->next[i]; if(!ch) ch = cur->f->next[i]; else { ch->f = cur->f->next[i]; ch->ended_val += ch->f->ended_val; Q.push(ch); } } } } int dp[52][1111]; char sol[52][1111][55],tmp[55],add[2]; bool less(char *a,char *b) { int la = strlen(a); int lb = strlen(b); return la < lb || la == lb && strcmp(a,b) < 0; } void solve(int n) { memset(dp,-1,sizeof(dp)); dp[0][0] = 0; sol[0][0][0] = add[1] = '\0'; for(int i=0;i<n;i++) { for(int j=0;j<top;j++) { if(dp[i][j] == -1) continue; for(int k=0;k<Size;k++) { add[0] = 'a' + k; strcpy(tmp,sol[i][j]); strcat(tmp,add); int jj = node[j].next[k] - node; int val = dp[i][j] + node[jj].ended_val; if(dp[i+1][jj] < val || dp[i+1][jj] == val && less(tmp,sol[i+1][jj])) { dp[i+1][jj] = val; strcpy(sol[i+1][jj],tmp); } } } } int mmax = 0; char ans[52]; ans[0] = '\0'; for(int i=1;i<=n;i++) for(int j=0;j<top;j++) { if(dp[i][j] > mmax || dp[i][j] == mmax && less(sol[i][j],ans)) { mmax = dp[i][j]; strcpy(ans,sol[i][j]); } } puts(ans); } } const int N = 52; char str[102][13]; int main() { //freopen("out.ads","w",stdout); int T,n,m; scanf("%d",&T); while(T--) { ACam::init(); scanf("%d%d",&n,&m); for(int i=0;i<m;i++) scanf("%s",str[i]); for(int i=0;i<m;i++) { int val; scanf("%d",&val); ACam::insert(str[i],val); } ACam::get_fail(); ACam::solve(n); } return 0; }
相关文章推荐
- 【软件工程】Word frequency program
- 点击劫持和图片覆盖劫持
- Leave the world behind,高山玫瑰不让须眉
- SVM入门(六)至(十)
- TFS2010安装易出现的问题及解决办法(win2008R2_64+SQL2008SP2+SharepointSp2+VS2012+TFS2010)
- android 2.3 开始主线程不能访问网络
- Sqlserver 数据库恢复常见错误及解决(网站转载 留着备用)
- JS 实现导航栏悬停效果(续2)
- uva 591 Box of Bricks
- Using VLANs with OVS and libvirt
- 转:vim插件 ctags 和 taglist 的安装和使用
- Delphi 调试BPL包中引用另外的BPL的方法。
- pycurl和lxml参考
- PHP冒泡排序详解
- java中的多线程
- sequencefile header
- 玩转千万级别的数据(二)
- gcc & gdb & 汇编 & linux c
- c# 类中的静态方法
- C#读取execl到datatable,设置execl单元格颜色