zoukankan      html  css  js  c++  java
  • Ring HDU

    构造n长串,若含有模板串x可获得a[x]的价值,同价值取字典序最小,输出路径

    dp[i][j]表示长度i转移态j的最大价值,对应一个path[i][j]记录路径

    #include<bits/stdc++.h>
    #include<stdio.h>
    #include<algorithm>
    #include<queue>
    #include<string.h>
    #include<iostream>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<iomanip>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define pb push_back
    #define FOR(a) for(int i=1;i<=a;i++)
    const int inf=0x3f3f3f3f;
    const int maxn=1e6+7; 
    const long long mod=1e9+7;
    const int sigma=26;
    
    ll ans;
    
    int a[110];
    int dp[55][1111];	//串长i匹配到j位置最大价值
    string path[55][1111];	//路径
    
    struct automata{  
        int ch[maxn][sigma];  
        int val[maxn];  
        int f[maxn];  
        int sz;  
      
        int newnode(){  
            memset(ch[sz],0,sizeof(ch[sz]));  
            f[sz]=val[sz]=0;  
            return sz++;  
        }  
      
        void init(){  
            memset(val,0,sizeof(val));  
            sz=0;  
            newnode();  
        }  
      
        void insert(char *s,int v){   
            int u=0;  
            int len=strlen(s);  
            for(int i=0;i<len;i++){  
                int id=s[i]-'a';  
                if(!ch[u][id])ch[u][id]=newnode();  
                u=ch[u][id]; 
            }  
        	val[u]=v;
    	}  
    	void solve(int n){
    		memset(dp,-1,sizeof dp);
    		dp[0][0]=0;path[0][0]="";
    		for(int i=0;i<n;i++){
    			for(int j=0;j<sz;j++){
    				if(dp[i][j]!=-1){	//可达,更新后继
    					for(int k=0;k<26;k++){
    						int u=ch[j][k];
    						if(dp[i][j]+a[val[u]] > dp[i+1][u]){
    							dp[i+1][u]=dp[i][j]+a[val[u]];
    							path[i+1][u]=path[i][j]+(char)(k+'a');
    							continue;
    						}
    						if(dp[i][j]+a[val[u]]==dp[i+1][u]){
    							string str=path[i][j];
    							str.pb(k+'a');
    							if(str<path[i+1][u])path[i+1][u]=str;
    						}
    					}
    				}
    			}
    		}
    		int ans=0,row;
    		string str; 
    		for(int i=0;i<=n;i++)
    			for(int j=0;j<sz;j++)
    				if(ans<dp[i][j]){
    					ans=dp[i][j];row=i;
    				}
    			
    		
    		if(ans==0){printf("
    ");return;}
    		str="";
    		for(int j=0;j<sz;j++){
    			if(dp[row][j] == ans && (str>path[row][j]||str==""))
    				str=path[row][j];
    		}
    		cout<<str<<endl;
    	}
      
        void build(){  
            queue<int>q;  
            q.push(0);    
            while(!q.empty()){  
                int u=q.front();q.pop();  
                if(val[f[u]]){ 
                	//val[u]=(val[u]+val[f[u]];  
                	a[val[u]]+=a[val[f[u]]];
    			}  	
                for(int i=0;i<sigma;i++){  
                    int v=ch[u][i];  
                    if(!v)ch[u][i]=ch[f[u]][i];  
                    else q.push(v);  
                    if(u&&v)f[v]=ch[f[u]][i];  
                }  
            }  
        }  
         
    }ac; 
    
    char buf[60];
    int n,m;
    int main(){
    	int T;scanf("%d",&T);
    	while(T--){
    		scanf("%d%d",&n,&m);
    		ac.init();
    		for(int i=1;i<=m;i++){
    			scanf("%s",buf);
    			ac.insert(buf,i);
    		}
    		for(int i=1;i<=m;i++)scanf("%d",&a[i]);
    		ac.build();ac.solve(n);
    	}
    }


  • 相关阅读:
    八、Docker+RabbitMQ
    Spring.Net学习笔记一(IOC第一个实例)
    快速搞懂 SQL Server 的锁定和阻塞
    JQuery.Ajax()的data参数类型
    常用开源介绍
    AutoMapper简明教程(学习笔记)
    面向.Net程序员的前端优化
    --数组元素插入有两种方式
    JQuery源码分析-02正则表达式-RegExp-常用正则表达式
    关于ASP.NET MVC的Filter小记
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611275.html
Copyright © 2011-2022 走看看