zoukankan      html  css  js  c++  java
  • BZOJ3139 [Hnoi2013]比赛

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

    本文作者:ljh2000
    作者博客:http://www.cnblogs.com/ljh2000-jump/
    转载请注明出处,侵权必究,保留最终解释权!

    题目链接:BZOJ3139

    正解:搜索+hash

    解题报告:

      考虑直接爆搜的话,就是枚举当前的与之后的每一个比赛的结果是什么,但是复杂度很高。

      优化的话,考虑我枚举完一个的得分之后,剩下的状态打乱顺序不会影响最终结果,因为前面的贡献已经计算完毕了。

      那么我每次从小到大排序,并且把状态压起来,记忆化一下,就可以通过官方数据了,还有诸如鸡兔同笼和得分上限的剪枝也可以加。

    //It is made by ljh2000
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <ctime>
    #include <vector>
    #include <queue>
    #include <map>
    #include <set>
    #include <string>
    #include <complex>
    using namespace std;
    typedef long long LL;
    typedef long double LB;
    typedef complex<double> C;
    const double pi = acos(-1);
    const int MAXN = 12;
    const int mod = 1000000007;
    LL ans;
    int n,a[MAXN];
    map<LL,bool>use[MAXN];
    map<LL,int>f[MAXN];//不能直接把状态设为S,需要考虑当前处理的左端点和右端点!
    inline bool cmp(int q,int qq){ return q<qq; }
    inline int getint(){
        int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
        if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
    }
    
    inline LL gethash(int *val){
    	LL tot=0;
    	for(int i=1;i<=n;i++) 
    		tot=tot*29+val[i];
    	return tot;
    }
    
    int dfs(int *val,int l,int r){
    	if(l>=r) {
    		if(val[l]!=0) return 0;
    		if(l==n) return 1;
    		int b[MAXN]; for(int i=1;i<=n;i++) b[i]=val[i];
    		sort(b+l+1,b+n+1,cmp);//对于后继的一个状态,sort之后不会有影响
    		LL S=gethash(b); 
    		if(use[l+1][S]) return f[l+1][S];
    		f[l+1][S]=dfs(b,l+1,n);
    		use[l+1][S]=1;
    		return f[l+1][S];
    	}
    
    	if(3*(r-l)<val[l]) return 0;
    	int tot=0;
    	if(val[l]>=3) {
    		val[l]-=3;
    		tot+=dfs(val,l,r-1); tot%=mod;
    		val[l]+=3;
    	}
    
    	if(val[l]>=1 && val[r]>=1) {
    		val[l]--; val[r]--;
    		tot+=dfs(val,l,r-1); tot%=mod;
    		val[l]++; val[r]++;
    	}
    
    	if(val[r]>=3) {
    		val[r]-=3;
    		tot+=dfs(val,l,r-1); tot%=mod;
    		val[r]+=3;
    	}
    
    	return tot;
    }
    
    inline void work(){
    	n=getint(); for(int i=1;i<=n;i++) a[i]=getint();
    	sort(a+1,a+n+1,cmp);
    	ans=dfs(a,1,n);
    	printf("%lld",ans);
    	//cout<<endl<<clock()<<endl;
    }
    
    int main()
    {
        work();
        return 0;
    }
    

      

  • 相关阅读:
    绿色简洁供应商采购后台管理系统模板——后台
    通用的电子商务商城后台管理界面模板——后台
    透明的企业网站卡通后台模板——后台
    绿色的宠物店cms后台管理系统模板——后台
    蓝色的cms企业记账管理后台模板源码——后台
    简洁的响应式博客后台管理模板——后台
    基于bootstrap物资管理系统后台模板——后台
    黑色的网站后台管理系统ui界面——后台
    蓝色的企业后台cms管理系统——后台
    黑色的cms商城网站后台管理模板——后台
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/6485706.html
Copyright © 2011-2022 走看看