zoukankan      html  css  js  c++  java
  • [SDOI2007]游戏

    XXX.[SDOI2007]游戏

    STL的百种用法

    可以观察到可以接龙的对构成一张DAG。因此我们要找到DAG中最长路。这个随便DP就可以了。

    关键是找到可以互相转移的位置。

    \(n^2\)枚举非常危险,因为还有一个\(26\)判断的常数,没试,估计过不了。

    我们必须寻找复杂度更低的算法。

    发现一个串只与组成它的每个字符的数量有关。那么我们可以把这每个字符的数量压到一个vector里面,然后用map<vector<int>,int>来找可以转移的位置。或者因为串长\(\leq 100\),因此vector中每个数必定不超过\(100\),然后可以化成一个string。当然,string也可以哈希(虽然答案就不一定正确了)。

    当然,无论怎么搞,都有一个\(26\)的常数(似乎哈希一下复杂度是\(26n\log n\),而不哈希复杂度是\(26^2\log n\))。但不管怎么说,能过。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    string s[10010];
    map<vector<int>,int>m;
    int S,n,f[10010],pre[10010],mp;
    void print(int i){
    	if(!i)return;
    	print(pre[i]);
    	cout<<s[i]<<endl;
    }
    int main(){
    	n++;
    	while(cin>>s[n])n++;
    	sort(s+1,s+n);
    	for(int i=1;i<n;i++){
    		f[i]=1;
    		vector<int>v;
    		v.resize(26);
    		for(auto j:s[i])v[j-'a']++;
    		m[v]=i;
    	}
    	for(auto i:m){
    		vector<int>v=i.first;
    		for(int k=0;k<26;k++){
    			v[k]++;
    			if(m.find(v)!=m.end()){
    				int j=m[v];
    				if(f[j]<f[i.second]+1)f[j]=f[i.second]+1,pre[j]=i.second;
    			}
    			v[k]--;
    		}
    	}
    	for(int i=1;i<n;i++)if(f[i]>f[mp])mp=i;
    	printf("%d\n",f[mp]);
    	print(mp);
    	return 0;
    }
    

  • 相关阅读:
    微软企业库5.0学习笔记实战数据验证模块高级篇
    总结一些常用的CMS
    JS类库
    sql2
    前端开发必须知道的CSS
    JS实现非图片动态loading
    Microsoft SQL Server 2005 提供了一些工具来监控数据库
    js实现Tooltip
    Js动画基础
    仿iGoogle自定义首页模块拖拽
  • 原文地址:https://www.cnblogs.com/Troverld/p/14597082.html
Copyright © 2011-2022 走看看