HDU2296 Ring AC自动机+DP
来源:互联网 发布:方正卡通字体优化 编辑:程序博客网 时间:2024/06/10 07:00
题目链接:点击打开链接
题目大意:有m个关键字,每个关键字有一个权值,让构造出一个长度不大于n的目标串,使得该目标串的权值尽可能大。对于相同的权值的多个目标串,我们需要输出长度最小的一组,存在多个长度相同的目标串时输出字典序最小的一组。
分析:构造出tire树,对于树中的每一个节点我们看做为一个状态,定义dp(i,j)为前i个字符在状态j时的最大权值,string s(i,j)为该状态下的目标串。
实现代码如下:
#include <cstdio>#include <iostream>#include <cstring>#include <queue>#include <algorithm>using namespace std;#define INF 0x7fffffff#define son_num 26#define maxl 55#define maxn 1010int w[maxn]; //纪录每个关键字的权值int dp[maxl][maxn]; //dp[i][j]纪录长度为i的字符串在状态j时的最大总值char s[maxl][maxn][maxl]; //s[i][j]纪录在该状态下的字典序最小的序列bool cmp(char *s1,char *s2){ int len1=strlen(s1); int len2=strlen(s2); if(len1!=len2) return len1<len2; return strcmp(s1,s2)<0;}struct node{ int next[maxn][son_num]; int fail[maxn]; int terminal[maxn]; //纪录每一个关键字的编号 int root,size; int newnode() { for(int i=0;i<son_num;i++) next[size][i]=-1; terminal[size++]=-1; return size-1; } void init() { size=0; root=newnode(); } void insert(char *str,int id) { int p=root; int i=0; while(str[i]) { int index=str[i]-'a'; if(next[p][index]==-1) next[p][index]=newnode(); p=next[p][index]; i++; } terminal[p]=id; } void build_fail() { queue <int> que; fail[root]=root; for(int i=0;i<son_num;i++) { if(next[root][i]==-1) next[root][i]=root; else { fail[ next[root][i] ]=root; que.push(next[root][i]); } } while(!que.empty()) { int p=que.front(); que.pop(); for(int i=0;i<son_num;i++) { if(next[p][i]==-1) next[p][i]=next[ fail[p] ][i]; else { fail[ next[p][i] ]=next[ fail[p] ][i]; que.push(next[p][i]); } } } } void solve(int n) { for(int i=0;i<=n;i++) for(int j=0;j<size;j++) dp[i][j]=-INF; dp[0][0]=0; char ans[maxl],tmp[maxl]; int maxa=0; memset(s[0][0],0,sizeof(s[0][0])); memset(ans,0,sizeof(ans)); for(int i=0;i<n;i++) for(int j=0;j<size;j++) if(dp[i][j]>=0) { strcpy(tmp,s[i][j]); int len=strlen(tmp); for(int k=0;k<son_num;k++) { int cnt=next[j][k]; tmp[len]=k+'a'; tmp[len+1]='\0'; int cnt_dp=dp[i][j]; if(terminal[cnt]!=-1) cnt_dp+=w[ terminal[cnt] ]; if(dp[i+1][cnt]<cnt_dp||(dp[i+1][cnt]==cnt_dp&&cmp(tmp,s[i+1][cnt]))) { dp[i+1][cnt]=cnt_dp; strcpy(s[i+1][cnt],tmp); if(cnt_dp>maxa||(cnt_dp==maxa&&cmp(tmp,ans))) { maxa=cnt_dp; strcpy(ans,tmp); } } } } printf("%s\n",ans); }}AC;int main(){ char str[maxl]; int n,x,t; scanf("%d",&t); while(t--) { AC.init(); scanf("%d%d",&n,&x); for(int i=0;i<x;i++) { scanf("%s",str); AC.insert(str,i); } for(int i=0;i<x;i++) scanf("%d",&w[i]); AC.build_fail(); AC.solve(n); } return 0;}
0 0
- HDU2296--Ring--AC自动机+DP
- hdu2296---Ring(AC自动机+dp)
- HDU2296 Ring AC自动机+DP
- hdu2296 Ring (AC自动机+dp)
- AC自动机+dp打印路径 hdu2296 Ring
- AC自动机+DP+hdu2296
- hdu2296(AC自动机+DP)
- hdu2296 AC自动机+DP
- hdu2296-(AC自动机+DP)
- HDU2296(AC自动机+DP)
- hdu2296 AC自动机
- HDU 2296 Ring(AC自动机+DP)
- HDU 2296 Ring(AC自动机+DP)
- HDU 2296 Ring(AC自动机+DP)
- 【HDU】2296 Ring AC自动机+DP
- hdu 2296 Ring(AC自动机+DP)
- hdu 2296 Ring AC自动机+DP
- hdu 2296 Ring (ac自动机+dp)
- 函数声明与函数表达式在间隔与循环中的表现
- Android导出一个JAR库 Android如何将程序打成jar包 android 打包...
- layout_weight的使用
- 计算电磁学数值模式匹配算法实现
- 利用sqoop从数据源获取数据到hive的流程化
- HDU2296 Ring AC自动机+DP
- kbhit()实现程序启动时倒计时允许调试人员手动停止程序的运行方法
- SpringMVC访问静态资源实例讲解
- 顺序栈
- Java建造者模式(Builder模式)
- Reactjs官方文档(1)
- pl/sql
- 自旋锁和互斥锁区别
- 比较好点的博客