zoukankan      html  css  js  c++  java
  • CF1242CSum Balance【状压dp】

    正题

    题目链接:https://www.luogu.com.cn/problem/CF1242C


    题目大意

    给出\(k\)个集合,现在从每个集合中取出一个数再把这些数放进每个集合里各一个,求能否使得所有集合的和相等,求方案。

    保证所有集合中的出现过的数字都互不相同。

    \(1\leq k\leq 15,1\leq n_i\leq 5000,-10^9\leq a_{i,j}\leq 10^9\)


    解题思路

    显然的突破口肯定是数字互不相同。

    首先和不变所以每个集合的最后的和应该都是知道的记为\(sum\),记第\(i\)个集合的和为\(s_i\)

    考虑每个交换都是类似一个环形的结构,设\(b\)传给\(a\),记传出的数字为\(x_b\)\(x_a\),那么有

    \[s_a-x_a+x_b=sum\rightarrow x_b=sum-s_a+x_a \]

    因为互不相同,每个数字看成一个点,那么数字\(x_a\)连接的就是\(sum-s_a+x_a\)

    然后暴力找出所有没有经过重复集合数字的环,记录\(r_S\)表示集合\(S\)的环的起点。

    然后设\(f_S\)表示能否拼出集合\(S\),然后\(O(3^k)\)转移即可。

    时间复杂度:\(O(k\sum n+3^k)\)


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #define ll long long
    #define mp(x,y) make_pair(x,y)
    using namespace std;
    const ll K=16;
    ll k,sum,s[K],f[1<<(K-1)],r[1<<(K-1)];
    map<ll,ll> v;pair<ll,ll> ans[K];
    void solve(ll S){
    	if(!S)return;
    	ll x=r[f[S]]-1e9-1;
    	ll y=x,q=v[x];
    	do{
    		y+=sum-s[q];
    		ans[v[y]]=mp(y,q);
    		q=v[y];
    	}while(y!=x);
    	solve(S^f[S]);
    	return;
    }
    signed main()
    {
    	scanf("%lld",&k);
    	for(ll i=1;i<=k;i++){
    		ll m;scanf("%lld",&m);
    		for(ll j=1,x;j<=m;j++)
    			scanf("%lld",&x),s[i]+=x,v[x]=i;
    		sum+=s[i];
    	}
    	if(sum%k!=0)return puts("No")&0;
    	sum/=k;
    	map<ll,ll>::iterator it=v.begin();
    	while(it!=v.end()){
    		ll x=(*it).first,p=(*it).second;
    		ll S=0,q=p,y=x,flag=1;
    		do{
    			if(!q||(S>>q-1)&1)
    				{flag=0;break;}
    			S|=(1<<q-1);
    			y+=sum-s[q];q=v[y];
    		}while(y!=x);
    		if(flag)r[S]=x+1e9+1;
    		++it;
    	}
    	ll MS=(1<<k);f[0]=-1;
    	for(ll s=0;s<MS;s++){
    		for(ll t=s;t;t=(t-1)&s)
    			if(f[s^t]!=0&&r[t]){f[s]=t;break;}
    	}
    	if(!f[MS-1])return puts("No")&0;
    	puts("Yes");solve(MS-1);
    	for(ll i=1;i<=k;i++)
    		printf("%lld %lld\n",ans[i].first,ans[i].second);
    	return 0;
    }
    
  • 相关阅读:
    Django之POST GET与前后端交互
    Django中用户权限模块
    Django运算表达式与Q对象/F对象
    Django中Middleware中间件
    Form表单 JSON Content-type解析
    浅析ajax原理与用法
    浅析Django之session与cookie
    浅谈HTTP协议
    Django 项目搭建(ubuntu系统)
    h5 和之前版本的区别
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/15472874.html
Copyright © 2011-2022 走看看