程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 4534

HDU 4534

編輯:C++入門知識

AC自動機水題,想清楚狀態表示即可。

我一開始多設計一維狀態記錄之前用了多少個刪除操作,MLE,其實這個狀態不需要記錄的,作為一個待求最值的變量。


[cpp]
#include <cstdio>  
#include <cstring>  
#include <algorithm>  
#include <queue>  
#define N 1700  
using namespace std; 
const int INF=-((~(0U))>>1); 
char s[110]; 
int score; 
int next[N][26],pos,flag[N],sta[N],val[N],fail[N],tot; 
 
int newnode(){ 
    memset(next[pos],0,sizeof(next[pos])); 
    flag[pos]=fail[pos]=sta[pos]=val[pos]=0; 
    return pos++; 

 
void insert(char * s,int score){ 
    int p=0,i; 
    for(i=0;s[i];i++){ 
        int k=s[i]-'a'; 
        p=next[p][k]?next[p][k]:next[p][k]=newnode(); 
    } 
    if(score==999){ 
        flag[p]=1; 
        sta[p]=(1<<tot); 
        tot++; 
    } 
    else if(score==-999){ 
        flag[p]=-1; 
    } 
    else{ 
        flag[p]=2; 
        val[p]=score; 
    } 

 
void makefail(){ 
    queue<int>q; 
    q.push(0); 
    int i,p=0; 
    while(!q.empty()){ 
        int u=q.front(); 
        q.pop(); 
        for(i=0;i<26;i++){ 
            int v=next[u][i]; 
            if(v==0) next[u][i]=next[fail[u]][i]; 
            else q.push(v); 
            if(u&&v){ 
                fail[v]=next[fail[u]][i]; 
                if(flag[fail[v]]==-1){ 
                    flag[v]=-1; 
                } 
                else if(flag[v]!=-1){ 
                    sta[v]|=sta[fail[v]]; 
                    val[v]+=val[fail[v]]; 
                } 
            } 
        } 
    } 

 
int dp[2][260][N]; 
int cost[2][260][N]; 
void makeans(){ 
    int i,j,k,len,cur; 
    len=strlen(s); 
    cur=1; 
    for(j=0;j<(1<<tot);j++) 
        for(k=0;k<pos;k++) 
            dp[0][j][k]=-INF,cost[0][j][k]=INF; 
    dp[0][0][0]=0; 
    cost[0][0][0]=0; 
    for(i=0;s[i];i++){ 
        for(j=0;j<(1<<tot);j++) 
            for(k=0;k<pos;k++) 
                dp[cur][j][k]=-INF,cost[cur][j][k]=INF; 
        for(j=0;j<(1<<tot);j++){ 
            for(k=0;k<pos;k++){ 
                if(dp[cur^1][j][k]==-INF)continue; 
                if(dp[cur][j][k]>dp[cur^1][j][k]+1){ 
                    dp[cur][j][k]=dp[cur^1][j][k]+1; 
                    cost[cur][j][k]=cost[cur^1][j][k]; 
                } 
                else if(dp[cur][j][k]==dp[cur^1][j][k]+1){ 
                    cost[cur][j][k]=max(cost[cur][j][k],cost[cur^1][j][k]); 
                } 
            } 
        } 
        for(j=0;j<(1<<tot);j++){ 
            for(k=0;k<pos;k++){ 
                if(dp[cur^1][j][k]==-INF)continue; 
                int v=next[k][s[i]-'a']; 
                if(flag[v]==-1)continue; 
                //if((j|sta[v])==((1<<tot)-1)) printf("***%d %d %d %d\n",i,j,k,p);  
                if(dp[cur][j|sta[v]][v]>dp[cur^1][j][k]){ 
                    dp[cur][j|sta[v]][v]=dp[cur^1][j][k]; 
                    cost[cur][j|sta[v]][v]=cost[cur^1][j][k]+val[v]; 
                } 
                else if(dp[cur][j|sta[v]][v]==dp[cur^1][j][k]){ 
                    cost[cur][j|sta[v]][v]=max(cost[cur][j|sta[v]][v],cost[cur^1][j][k]+val[v]); 
                } 
            } 
        } 
        cur^=1; 
    } 
    int ans1=-INF; 
    int ans=INF; 
    for(j=0;j<pos;j++){ 
        if(dp[cur^1][(1<<tot)-1][j]<ans1){ 
            ans1=dp[cur^1][(1<<tot)-1][j]; 
            ans=cost[cur^1][(1<<tot)-1][j]; 
        } 
        else if(dp[cur^1][(1<<tot)-1][j]==ans1){ 
            ans=max(ans,cost[cur^1][(1<<tot)-1][j]); 
        } 
    } 
    if(ans1!=-INF){ 
        printf("%d %d\n",ans1,ans); 
        return ; 
    } 
    printf("Banned\n"); 

 
int main(){ 
    int t,T,n,i,j; 
    scanf("%d",&T); 
    for(t=1;t<=T;t++){ 
        scanf("%d",&n); 
        pos=0,newnode(); 
        tot=0; 
        for(i=1;i<=n;i++){ 
            scanf("%s %d",s,&score); 
            insert(s,score); 
        } 
        makefail(); 
        scanf("%s",s); 
        printf("Case %d: ",t); 
        makeans(); 
    } 
    return 0; 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define N 1700
using namespace std;
const int INF=-((~(0U))>>1);
char s[110];
int score;
int next[N][26],pos,flag[N],sta[N],val[N],fail[N],tot;

int newnode(){
    memset(next[pos],0,sizeof(next[pos]));
    flag[pos]=fail[pos]=sta[pos]=val[pos]=0;
    return pos++;
}

void insert(char * s,int score){
    int p=0,i;
    for(i=0;s[i];i++){
        int k=s[i]-'a';
        p=next[p][k]?next[p][k]:next[p][k]=newnode();
    }
    if(score==999){
        flag[p]=1;
        sta[p]=(1<<tot);
        tot++;
    }
    else if(score==-999){
        flag[p]=-1;
    }
    else{
        flag[p]=2;
        val[p]=score;
    }
}

void makefail(){
    queue<int>q;
    q.push(0);
    int i,p=0;
    while(!q.empty()){
        int u=q.front();
        q.pop();
        for(i=0;i<26;i++){
            int v=next[u][i];
            if(v==0) next[u][i]=next[fail[u]][i];
            else q.push(v);
            if(u&&v){
                fail[v]=next[fail[u]][i];
                if(flag[fail[v]]==-1){
                    flag[v]=-1;
                }
                else if(flag[v]!=-1){
                    sta[v]|=sta[fail[v]];
                    val[v]+=val[fail[v]];
                }
            }
        }
    }
}

int dp[2][260][N];
int cost[2][260][N];
void makeans(){
    int i,j,k,len,cur;
    len=strlen(s);
    cur=1;
    for(j=0;j<(1<<tot);j++)
        for(k=0;k<pos;k++)
            dp[0][j][k]=-INF,cost[0][j][k]=INF;
    dp[0][0][0]=0;
    cost[0][0][0]=0;
    for(i=0;s[i];i++){
        for(j=0;j<(1<<tot);j++)
            for(k=0;k<pos;k++)
                dp[cur][j][k]=-INF,cost[cur][j][k]=INF;
        for(j=0;j<(1<<tot);j++){
            for(k=0;k<pos;k++){
                if(dp[cur^1][j][k]==-INF)continue;
                if(dp[cur][j][k]>dp[cur^1][j][k]+1){
                    dp[cur][j][k]=dp[cur^1][j][k]+1;
                    cost[cur][j][k]=cost[cur^1][j][k];
                }
                else if(dp[cur][j][k]==dp[cur^1][j][k]+1){
                    cost[cur][j][k]=max(cost[cur][j][k],cost[cur^1][j][k]);
                }
            }
        }
        for(j=0;j<(1<<tot);j++){
            for(k=0;k<pos;k++){
                if(dp[cur^1][j][k]==-INF)continue;
                int v=next[k][s[i]-'a'];
                if(flag[v]==-1)continue;
                //if((j|sta[v])==((1<<tot)-1)) printf("***%d %d %d %d\n",i,j,k,p);
                if(dp[cur][j|sta[v]][v]>dp[cur^1][j][k]){
                    dp[cur][j|sta[v]][v]=dp[cur^1][j][k];
                    cost[cur][j|sta[v]][v]=cost[cur^1][j][k]+val[v];
                }
                else if(dp[cur][j|sta[v]][v]==dp[cur^1][j][k]){
                    cost[cur][j|sta[v]][v]=max(cost[cur][j|sta[v]][v],cost[cur^1][j][k]+val[v]);
                }
            }
        }
        cur^=1;
    }
    int ans1=-INF;
    int ans=INF;
    for(j=0;j<pos;j++){
        if(dp[cur^1][(1<<tot)-1][j]<ans1){
            ans1=dp[cur^1][(1<<tot)-1][j];
            ans=cost[cur^1][(1<<tot)-1][j];
        }
        else if(dp[cur^1][(1<<tot)-1][j]==ans1){
            ans=max(ans,cost[cur^1][(1<<tot)-1][j]);
        }
    }
    if(ans1!=-INF){
        printf("%d %d\n",ans1,ans);
        return ;
    }
    printf("Banned\n");
}

int main(){
    int t,T,n,i,j;
    scanf("%d",&T);
    for(t=1;t<=T;t++){
        scanf("%d",&n);
        pos=0,newnode();
        tot=0;
        for(i=1;i<=n;i++){
            scanf("%s %d",s,&score);
            insert(s,score);
        }
        makefail();
        scanf("%s",s);
        printf("Case %d: ",t);
        makeans();
    }
    return 0;
}


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved