hdu 2296 Ring (ac自动机+dp)
来源:互联网 发布:美图秀秀for mac 编辑:程序博客网 时间:2024/04/27 23:40
题意:
给出m个串,现在要得到长度<=n的串,这个串是有多个串组合而成,串之间可以重叠,每个串对应一个价值。现在要输出总价值最高的串,优先选择短的,字典序小的。
题解:
ac自动机上dp,dp[i][j] 长度为i结尾点为j的最大价值。path[i][j][1110]记录字符串。转移方程要好好理解,很神奇。具体看代码。
#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<map>#include<set>using namespace std;#define B(x) (1<<(x))typedef long long ll;const int oo=0x3f3f3f3f;const ll OO=1LL<<61;const ll MOD=20090717;const int maxn=1005;const int SIZE=1005;char str[maxn];int val[maxn];int dp[55][SIZE];char path[55][SIZE][55];struct AC{ int next[SIZE][26],fail[SIZE],end[SIZE],Q[SIZE*26]; int root,cnt; void Init() { cnt=0; root=newNode(); } int newNode() { for(int i=0;i<26;i++) next[cnt][i]=-1; end[cnt++]=-1; return cnt-1; } void Insert(char buff[],int id) { int now=root; int len=strlen(buff); for(int i=0,k;i<len;i++) { k=buff[i]-'a'; if(next[now][k]==-1) next[now][k]=newNode(); now=next[now][k]; } end[now]=id; } void build() { fail[root]=root; int front,rear; front=rear=0; int now=root; for(int i=0;i<26;i++) { if(next[now][i]==-1) next[now][i]=root; else { fail[next[now][i]]=root; Q[rear++]=next[now][i]; } } while(front<rear) { now=Q[front++]; for(int i=0;i<26;i++) { if(next[now][i]==-1) next[now][i]=next[fail[now]][i]; else { fail[next[now][i]]=next[fail[now]][i]; Q[rear++]=next[now][i]; } } } } 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; } void DP(int n,int m) { int mx=0; char ans[55]; strcpy(ans,""); memset(dp,-0x3f,sizeof dp); memset(path,0,sizeof path); dp[0][0]=0; strcpy(path[0][0],""); for(int i=0;i<n;i++) { for(int j=0;j<cnt;j++) if(dp[i][j]>=0) { char temp[55]; strcpy(temp,path[i][j]); int len=strlen(temp); for(int t=0;t<26;t++) { int k=next[j][t]; temp[len]='a'+t; temp[len+1]='\0'; int value=0; if(end[k]!=-1) value=val[end[k]]; if(dp[i+1][k]<dp[i][j]+value||(dp[i+1][k]==dp[i][j]+value&&cmp(temp,path[i+1][k]))) { dp[i+1][k]=dp[i][j]+value; strcpy(path[i+1][k],temp); if(dp[i+1][k]>mx||(dp[i+1][k]==mx&&cmp(temp,ans))) { mx=dp[i+1][k]; strcpy(ans,temp); } } } } } printf("%s\n",ans); }};AC ac;int main(){ int n,m,T; scanf("%d",&T); while(T--) { scanf("%d %d",&n,&m); ac.Init(); for(int i=1;i<=m;i++) { scanf("%s",str); ac.Insert(str,i); } for(int i=1;i<=m;i++) scanf("%d",&val[i]);//cout<<"^_^"<<endl; ac.build(); ac.DP(n,m); } return 0;}/** 10 2 2helloworld4 1 1icpc10 0 00 0 0*/
0 0
- 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)
- 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)
- HDU 2296 Ring(AC自动机+DP)
- HDU 2296 Ring (AC自动机+DP,5级)
- HDU 2296 Ring(AC自动机 + DP 记录方案)
- HDU 2296 Ring AC自动机上的DP
- 网络常识
- Linux程序设计(Linux shell编程三)
- Configuring Java CAPS for SSL Support - Index
- 九度OJ题目1034:寻找大富翁
- 又一版“畅通工程”
- hdu 2296 Ring (ac自动机+dp)
- Public Keys, Private Keys, and Certificates
- POJ 2001 Shortest Prefixes (Trie树应用 好题)
- 【POJ2176】Pebbles
- Configuring Java CAPS for SSL Support - Program
- Configuring Java CAPS for SSL Support - Project
- 关于Ubuntu无法进入图形桌面的问题
- Configuring Java CAPS for SSL Support - Adapters
- Ext2文件系统初步