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

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3139

    思路:记忆化搜索

    首先每个队最多只会得27分,27^10还是没有炸longlong的,所以可以用hash存下来。

    每个队没有本质区别,所以每层搜索前先排好序,再来一层搜索枚举出当前队和剩余队的输赢情况,转化成子问题继续递归处理。

    据说状态数很多,但还是可以接受的。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    const int maxn=12,mod=37779,bas=23,maxt=1500010,pp=1000000007;
    typedef long long ll;
    using namespace std;
    int n,a[maxn],tim;
    struct hash{
    	int pre[maxt],now[100010],tot;ll val[maxt],sta[maxt];
    	ll find(ll x){
    		int u=x%mod;
    		for (int y=now[u];y;y=pre[y]) if (sta[y]==x) return val[y];
    		return -1;
    	}
    	void add(ll x,ll cnt){int u=x%mod;pre[++tot]=now[u],now[u]=tot,sta[tot]=x,val[tot]=cnt;}
    }h;
    //void print(int a[]){for (int i=0;i<=n;i++) printf("%d ",a[i]);puts("");}
    ll encode(int a[]){
    	ll res=0;
    	for (int i=0;i<=n;i++) res=res*30+a[i];
    	return res;
    }
    void decode(int a[],ll x){for (int i=n;i>=0;i--) a[i]=x%30,x/=30;}
    ll dfs1(ll x);
    ll dfs(int a[],int x,int y){
    	ll ans=0;
    	//if ((++tim)%10000==0) printf("%d
    ",tim);
    	if (y>n){
    		if (!a[x]){
    			int t[maxn];
    			for (int i=1;i<=n;i++) t[i]=a[i];
    			sort(t+1,t+1+n),t[0]=x;
    			return dfs1(encode(t));
    		}
    		else return 0;
    	}
    	a[x]-=3;
    	if (a[x]>=0&&a[y]>=0) ans+=dfs(a,x,y+1);
    	a[x]+=3,a[y]-=3;
    	if (a[x]>=0&&a[y]>=0) ans+=dfs(a,x,y+1);
    	a[y]+=3,a[x]--,a[y]--;
    	if (a[x]>=0&&a[y]>=0) ans+=dfs(a,x,y+1);
    	a[x]++,a[y]++;return ans;
    }
    
    ll dfs1(ll x){
    	ll tmp=h.find(x);
    	if (tmp!=-1) return tmp;
    	int b[maxn];decode(b,x); //if (tim%10000==0)print(b);
    	if (b[0]==n&&b[n]==0) return 1;
    	ll sum=dfs(b,b[0]+1,b[0]+2);
    	h.add(x,sum);return sum;
    }
    
    int main(){
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    	sort(a+1,a+1+n),printf("%lld
    ",dfs1(encode(a))%pp);
    	return 0;
    }
    
    /*
    10
    21 12 16 8 3 4 7 20 12 13
    */



  • 相关阅读:
    前端下拉框
    使用Redis的有序集合实现排行榜功能
    python--list,str,dict,json,tuple互换用法实例
    微信支付
    C++创建及访问动态对象
    C++动态持久内存分配(new)
    C++函数与指针
    C++数组与指针
    C++指针基础
    MySQL再安装
  • 原文地址:https://www.cnblogs.com/thythy/p/5493489.html
Copyright © 2011-2022 走看看