• Codeforces 1242C


    先判一下能不能均分,不能就gg,否则设平均数为(ave),第(i)个盒子中的数的和为(sum_i)

    然后考虑枚举一个盒子中扔掉一个数(x),那么由于所有数两两不同,那么可以找到一个唯一的(y)扔进这个盒子,使其等于(ave)

    这里显然可以通过(sum_i+y-x=ave)反解出(y=ave+x-sum_i)

    这样不停的找前驱,就是一个找环的过程

    然后如果一个环能闭上,那么就是一个合法的集合

    对于集合之间,最后做一次子集DP就行了

    输出方案的话记一下DP的前驱状态和每个合法集合的构成即可

    复杂度(O(k^2n+3^k))

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 int k;
     5 ll s,sum[16];
     6 vector<ll> a[16];
     7 unordered_map<ll,int> has[16];
     8 bool vis[16];
     9 bool iscir[40005],dp[40005];
    10 int pp[40005];
    11 struct Node
    12 {
    13     int from,to;
    14     ll val;
    15     Node(int F=0,int T=0,ll V=0){from=F;to=T;val=V;}
    16 };
    17 bool operator < (Node A,Node B){return A.from<B.from;}
    18 vector<Node> Ans[40005];
    19 void go(int pos,ll val)
    20 {
    21     memset(vis,0,sizeof(vis));
    22     int u=pos;
    23     ll w=s+val-sum[u];
    24     vector<Node> tmp;tmp.clear();
    25     while(1)
    26     {
    27         int pre=-1;
    28         for(int i=0;i<k;++i)if(has[i][w]){pre=i;break;}
    29         if(pre==-1)return;
    30         tmp.push_back(Node(pre,u,w));
    31         u=pre;
    32         if(vis[u])return;
    33         vis[u]=1;
    34         if(u==pos)break;
    35         w=s+w-sum[u];
    36     }
    37     if(val!=w)return;
    38     int S=0;
    39     for(int i=0;i<k;++i)if(vis[i])S|=(1<<i);
    40     iscir[S]=1;
    41     Ans[S]=tmp;
    42 }
    43 vector<Node> res;
    44 void print(int S)
    45 {
    46     if(!S)return;
    47     for(Node u:Ans[S^pp[S]])res.push_back(u);
    48     print(pp[S]);
    49 }
    50 int main()
    51 {
    52     scanf("%d",&k);
    53     s=0;
    54     for(int sz,i=0;i<k;++i)
    55     {
    56         scanf("%d",&sz);
    57         while(sz--)
    58         {
    59             ll x;scanf("%I64d",&x);
    60             a[i].push_back(x);
    61             has[i][x]=1;
    62             sum[i]+=x;
    63         }
    64         s+=sum[i];
    65     }
    66     if(s%k)puts("No");
    67     else
    68     {
    69         s/=k; 
    70         for(int i=0;i<k;++i)
    71             for(ll x:a[i])go(i,x);
    72         dp[0]=1;
    73         for(int S=1;S<(1<<k);++S)
    74         {
    75             for(int s=S;s;s=(s-1)&S)if(dp[S^s]&iscir[s])
    76             {
    77                 dp[S]=1;
    78                 pp[S]=S^s;
    79             }
    80         }
    81         if(!dp[(1<<k)-1])puts("No");
    82         else
    83         {
    84             puts("Yes");
    85             res.clear();
    86             print((1<<k)-1);
    87             sort(res.begin(),res.end());
    88             for(Node u:res)printf("%I64d %d
    ",u.val,u.to+1);
    89         }
    90     }
    91 }
    View Code
  • 相关阅读:
    Java Servlet(十):JSTL核心标签库
    Java Servlet(九):转发请求与重定向请求区别
    Java tomcat启动失败(Servlet3.0 Web Project):A child container failed during start
    快速安装服务
    Java Servlet(八):EL自定义函数
    Java Servlet(七):JavaWeb MVC 操作(jdk7+tomcat7+eclipse)
    新版mysql(mysql-5.7.12-winx64)安装
    oracle之 oradebug 命令用法
    Linux 绑定双网卡
    Linux 之 NTP 服务 服务器
  • 原文地址:https://www.cnblogs.com/uuzlove/p/12310237.html
Copyright © 2020-2023  润新知