Codeforces Round #432 (Div. 1, based on IndiaHacks Final Round 2017) D. Tournament Construction(dp + 构造)
题意
一个竞赛图的度数集合是由该竞赛图中每个点的出度所构成的集合。
现给定一个 \(m\) 个元素的集合,第 \(i\) 个元素是 \(a_i\) 。(此处集合已经去重)
判断其是否是一个竞赛图的度数集合,如果是,找到点数最小的满足条件的竞赛图,并构造方案。
\(m, a_i \le 30\) ,\(a_i\) 互不相同。
题解
首先给出结论:假如给出每个点的出度,那么这些点能形成一个竞赛图当且仅当排序后的序列 \(d_1, d_2, d_3, \dots , d_n\) 满足对于所有 \(k < n\) 有 \(\displaystyle \sum _{k_i=1}^{k} d_i ≥ {k \choose 2}\) 且 \(\displaystyle \sum_{i = 1} ^ {n} d_i = {n \choose 2}\) 。
考虑证明,不难发现对于竞赛图的任意点集 \(S\) ,都必须满足 \(\displaystyle \sum_{i \in S} d_i \ge {|S| \choose 2}\) ,因为点集 \(S\) 之间的一对点至少会存在一条边贡献一个出度。
并且由于
\]
所以发现最后的点数是 \(O(\max \{a_i\})\) 级别的,其实最多就是 \(2 \max \{a_i\} + 1\) 。
那么就可以 \(dp\) 了,先将给定集合中的元素从小到大排序。
设 \(f[i][j][sum]\) 表示考虑完前 \(i\) 个元素,当前图中已经有 \(j\) 个点了,度数之和为 \(sum\) 是否可行。
对于这个 \(dp\) 转移时枚举下一个元素出现了几次就行了。
然后我们只需要找到一个最小的 \(i\) 使得 \(\displaystyle f[n][i][{i \choose 2}]\) 满足就行了,这个就是合法点数。
似乎一定可以构造出方案。。不存在无解qwq 至于原因,可以去问 zhou888 。
然后需要构造方案,我们转移 \(dp\) 的时候多记一下当前如何转移的就行了,最后逆推回去就得到了度数可重集合。
然后我们用这个度数可重集合来构造答案,每次将度数从小到大排序,然后把第一个点向后面出度个点连边就行了,不难发现这样一定可以构造出一组合法解。
最后复杂度就是 \(O(n{a_i}^3)\) 的,可以通过qwq
总结
对于竞赛图可以考虑任意一个子集度数都不少于 \(\displaystyle {n \choose 2}\) 的性质。
然后考虑构造图的时候可以贪心的去暴力分配度数,或者用网络流模拟这个过程也行qwq
代码
用了 goto
以及 lambda
函数等骚操作。。
#include <bits/stdc++.h>
#define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Set(a, v) memset(a, v, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define debug(x) cout << #x << ": " << (x) << endl
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
using namespace std;
template<typename T> inline bool chkmin(T &a, T b) {return b < a ? a = b, 1 : 0;}
template<typename T> inline bool chkmax(T &a, T b) {return b > a ? a = b, 1 : 0;}
inline int read() {
int x(0), sgn(1); char ch(getchar());
for (; !isdigit(ch); ch = getchar()) if (ch == '-') sgn = -1;
for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
return x * sgn;
}
void File() {
#ifdef zjp_shadow
freopen ("D.in", "r", stdin);
freopen ("D.out", "w", stdout);
#endif
}
const int Maxn = 35, N = 65;
bitset<2510> dp[Maxn][N], pre[Maxn][N];
int n, m, a[N], d[N], sum[N]; bitset<N> vis, G[N];
inline int Comb(int x) {
return x * (x - 1) / 2;
}
int main () {
File();
n = read();
For (i, 1, n) a[i] = read();
sort(a + 1, a + n + 1);
For (i, 1, n) sum[i] = sum[i - 1] + a[i];
dp[0][0][0] = true;
int pos = n;
For(j, 1, 61) For (i, 1, n) {
For (k, max(sum[i], Comb(j)), j * 30) {
if (dp[i - 1][j - 1][k - a[i]]) dp[i][j][k] = pre[i][j][k] = true;
if (dp[i][j - 1][k - a[i]]) dp[i][j][k] = !(pre[i][j][k] = false);
}
if (dp[n][j][Comb(j)]) { n = j; goto tag; }
}
tag: ;
int deg = Comb(n);
Fordown (i, n, 1)
d[i] = a[pos], pos -= pre[pos][i][deg], deg -= d[i];
int id[N], len;
For (i, 1, n) {
len = 0;
For (j, 1, n) if (!vis[j]) id[++ len] = j;
sort(id + 1, id + len + 1, [&](int lhs, int rhs) { return d[lhs] < d[rhs]; });
vis[id[1]] = true;
For (j, 2, d[id[1]] + 1) G[id[1]][id[j]] = true;
For (j, d[id[1]] + 2, len) G[id[j]][id[1]] = true, -- d[id[j]];
}
printf ("%d\n", n);
For (i, 1, n)
For (j, 1, n + 1)
putchar (j == jend ? '\n' : G[i][j] + '0');
return 0;
}
Codeforces Round #432 (Div. 1, based on IndiaHacks Final Round 2017) D. Tournament Construction(dp + 构造)的更多相关文章
- D. Arpa and a list of numbers Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017)
http://codeforces.com/contest/851/problem/D 分区间操作 #include <cstdio> #include <cstdlib> # ...
- Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017)ABCD
A. Arpa and a research in Mexican wave time limit per test 1 second memory limit per test 256 megaby ...
- 【前缀和】【枚举倍数】 Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017) D. Arpa and a list of numbers
题意:给你n个数,一次操作可以选一个数delete,代价为x:或者选一个数+1,代价y.你可以进行这两种操作任意次,让你在最小的代价下,使得所有数的GCD不为1(如果全删光也视作合法). 我们从1到m ...
- 【推导】【暴力】Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017) C. Five Dimensional Points
题意:给你五维空间内n个点,问你有多少个点不是坏点. 坏点定义:如果对于某个点A,存在点B,C,使得角BAC为锐角,那么A是坏点. 结论:如果n维空间内已经存在2*n+1个点,那么再往里面添加任意多个 ...
- 【推导】Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017) B. Arpa and an exam about geometry
题意:给你平面上3个不同的点A,B,C,问你能否通过找到一个旋转中心,使得平面绕该点旋转任意角度后,A到原先B的位置,B到原先C的位置. 只要A,B,C构成等腰三角形,且B为上顶点.那么其外接圆圆心即 ...
- Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017) D
Arpa has found a list containing n numbers. He calls a list bad if and only if it is not empty and g ...
- Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017) C
You are given set of n points in 5-dimensional space. The points are labeled from 1 to n. No two poi ...
- Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017) B
Arpa is taking a geometry exam. Here is the last problem of the exam. You are given three points a, ...
- Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017) A
Arpa is researching the Mexican wave. There are n spectators in the stadium, labeled from 1 to n. Th ...
随机推荐
- 利用tushare进行对兴业银行股价的爬取,并使用numpy进行分析
import sysimport tushare as tsimport numpy as npdata=ts.get_h_data('601066')print(data)#读出兴业银行7列数据da ...
- 一种简单有效的VBA源代码加密办法,支持64位宿主,适用于大部分VBA代码加密
原始出处:http://www.cnblogs.com/Charltsing/p/EncryptVBACode.html VBA代码加密是个老生常谈的问题,自从本人的VBA Dumper发布之后,在O ...
- 【学习总结】Git学习-参考廖雪峰老师教程二-安装Git
学习总结之Git学习-总 目录: 一.Git简介 二.安装Git 三.创建版本库 四.时光机穿梭 五.远程仓库 六.分支管理 七.标签管理 八.使用GitHub 九.使用码云 十.自定义Git 期末总 ...
- Docker防主机意外断电导致容器实例无法驱动解决方案:UPS || write barrier || 上btrfs定期snapshot
Write barrier - Wikipediahttps://en.wikipedia.org/wiki/Write_barrier R大在在介绍CMS时提到了write barrier写屏蔽的概 ...
- python生成个性二维码学习笔记
在linux环境下进行编码 1.先进家目录,自行创建Code文件夹 cd Code 2.下载MyQR库 sudo pip3 install MyQR 3.下载所需资源文件并解压 Code/ $ wge ...
- 12 Connections
1 and 出现在两个及以上的词,词组,或者句子之间,将它们连接起来.在正式的书面英语中,and不能出现在句首.在非正式的英语中可以. We should expand our product lin ...
- [转帖]ODBC、OLEDB、ADO、ADO.NET
一文详解ODBC.OLEDB.ADO.ADO.NET之间的关系 2019年01月16日 21:28:38 LoveMIss-Y 阅读数:66更多 所属专栏: 白话C#高级编程 版权声明:本文为博主 ...
- MySQL5.5 安装配置方法教程
MySQL下载地址:http://dev.mysql.com/downloads/installer/ 1.首先进入的是安装引导界面 2.然后进入的是类型选择界面,这里有3个类型:Typical(典型 ...
- MyBatis映射文件5
返回map Map<String,Object> getEmpByResMap(Integer id); <select id="getEmpByResMap&qu ...
- Numpy中array数据操作
1.创建: import numpy as np arr=np.array([1,2,3]) print(arr,arr.ndim) list=[1,2,3] arr=np.array(list) 2 ...