HDU 2296 Ring(AC自动机+DP)
2014-02-03 12:28
288 查看
题意:给出m个串,每个串都有一个价值,现在要构造一个长度小于等于n的串,使得其包含的价值最大,如果有两个串价值相同,则选择长度较小的,还相同选择字典序小的。
思路:首先自然是构建ac自动机,然后dp的思路也是比较明显的,dp[i][j]表示长度为i的串在状态j的时候的最大价值。由于要求结果的串,写起来还不是很顺畅……用pa[i][j]记录到当前状态最小的串,然后各种比较……
代码:
思路:首先自然是构建ac自动机,然后dp的思路也是比较明显的,dp[i][j]表示长度为i的串在状态j的时候的最大价值。由于要求结果的串,写起来还不是很顺畅……用pa[i][j]记录到当前状态最小的串,然后各种比较……
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<set> #include<stack> #include<cmath> #include<vector> #define inf 0x3f3f3f3f #define Inf 0x3FFFFFFFFFFFFFFFLL #define eps 1e-9 #define pi acos(-1.0) using namespace std; typedef long long ll; const int maxn=1500; int ch[maxn][26],next[maxn],lastv[maxn],val[maxn],size; void Init() { memset(ch[0],0,sizeof(ch[0])); memset(next,0,sizeof(next)); memset(lastv,0,sizeof(lastv)); size=val[0]=0; } void Insert(const char *s,int v) { int u=0,n=strlen(s); for(int i=0;i<n;++i) { int c=s[i]-'a'; if(!ch[u][c]) { ch[u][c]=++size; memset(ch[size],0,sizeof(ch[size])); val[size]=0; } u=ch[u][c]; } val[u]=v; } void build() { queue<int>q; for(int c=0;c<26;++c) if(ch[0][c]) q.push(ch[0][c]); int r,u,v; while(!q.empty()) { r=q.front();q.pop(); for(int c=0;c<26;++c) { u=ch[r][c]; if(!u) {ch[r][c]=ch[next[r]][c];continue;} q.push(u); v=next[r]; while(v&&!ch[v][c]) v=next[v]; next[u]=ch[v][c]; lastv[u]=val[next[u]]?next[u]:lastv[next[u]]; } } } int dp[55][maxn],h[maxn]; string pa[55][maxn]; int w[maxn],maxval,n,m; char str[110]; void solve() { memset(w,0,sizeof(w)); for(int i=0;i<=size;++i) { if(val[i]||lastv[i]) { int u=val[i]?i:lastv[i]; while(u) { w[i]+=h[val[u]]; u=lastv[u]; } } } for(int i=0;i<=n;++i) for(int j=0;j<=size;++j) pa[i][j].clear(); memset(dp,0xff,sizeof(dp)); maxval=0; int pos=0,st=0; dp[0][0]=0; for(int i=0;i<n;++i) for(int j=0;j<=size;++j) { if(dp[i][j]==-1) continue; for(int c=0;c<26;++c) { int u=ch[j][c]; if(dp[i][j]+w[u]>dp[i+1][u]) { dp[i+1][u]=dp[i][j]+w[u]; pa[i+1][u]=pa[i][j]+(char)(c+'a'); } else if(dp[i][j]+w[u]==dp[i+1][u]&&(pa[i][j]+(char)(c+'a'))<pa[i+1][u]) pa[i+1][u]=pa[i][j]+(char)(c+'a'); if(dp[i+1][u]>maxval) { maxval=dp[i+1][u]; //cout<<pa[i+1][u]<<endl; pos=i+1,st=u; } else if(dp[i+1][u]==maxval) { int la=pa[i+1][u].length(); int lb=pa[pos][st].length(); if(la<lb) pos=i+1,st=u; else if(la==lb&&pa[i+1][u]<pa[pos][st]) pos=i+1,st=u; } } } cout<<pa[pos][st]<<endl; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); Init(); for(int i=1;i<=m;++i) { scanf("%s",str); Insert(str,i); } for(int i=1;i<=m;++i) scanf("%d",&h[i]); build(); solve(); } return 0; }
相关文章推荐
- hdu2296---Ring(AC自动机+dp)
- HDU2296——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(自动机+DP)
- Ring - HDU 2296(自动机+dp)
- hdu 2296(AC自动机+dp)
- hdu 2296(ac自动机+dp)
- hdu 4758 - Walk Through Squares(AC自动机+DP)现场赛
- Hdu 4057 Rescue the Rabbit (AC自动机+状态压缩dp) - 2011 ACM-ICPC Dalian Regional Contest Problem G