Educational Codeforces Round 55 (Rated for Div. 2) Solution
A. Vasya and Book
Solved.
三种方式取$Min$
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define INF 0x3f3f3f3f3f3f3f3f
int t;
ll n, x, y, d; ll calc(ll x)
{
return x % d == ? x / d : x / d + ;
} int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%lld%lld%lld%lld", &n, &x, &y, &d);
ll res = INF;
if ((abs(y - x)) % d == ) res = min(res, (abs(y - x) / d));
if ((y - ) % d == ) res = min(res, calc(x) + (y - ) / d);
if ((n - y) % d == ) res = min(res, calc(n - x) + (n - y) / d);
if (res == INF) res = -;
printf("%lld\n", res);
}
return ;
}
B. Vova and Trophies
Solved.
合并相同种类,再判断是否有单独的S使得替换掉它合并后得到更优解
#include <bits/stdc++.h>
using namespace std; #define N 100010
#define pii pair <int, int>
int n, m;
char s[N];
pii a[N]; int main()
{
while (scanf("%d", &n) != EOF)
{
scanf("%s", s + );
int tot = s[] == 'G', m = , tmp = ;
for (int i = ; i <= n; ++i)
{
tot += s[i] == 'G';
if (s[i] != s[i - ])
{
a[++m] = pii(tmp, s[i] == 'G');
tmp = ;
}
++tmp;
}
a[++m] = pii(tmp, s[n] != 'G');
int res = ;
for (int i = ; i <= m; ++i)
{
if (a[i].second == )
res = max(res, min(tot, a[i].first + ));
else if (i != && i != m && a[i].first == )
res = max(res, min(tot, a[i - ].first + + a[i + ].first));
}
printf("%d\n", res);
}
return ;
}
C. Multi-Subject Competition
Solved.
题意:
有一个多学科竞赛,一名队员只会一门学科
派出去的队伍对于每个要参加的学科其参加的人数要相等
并且每个队员对于其会的那门学科有一个技能值
求如何派出队伍参加学科使得队伍中所有队员的技能值总和最大。
思路:
枚举要参加的学科派出的队员数,网上枚举,不符合条件的学科消除影响,每名队员只会遍历一次
时间复杂度$O(n)$
#include <bits/stdc++.h>
using namespace std; #define N 100010
int n, m;
vector <int> v[N];
int tot[N];
queue <int> q; int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = ; i <= m; ++i) v[i].clear();
memset(tot, , sizeof tot);
while (!q.empty()) q.pop();
for (int i = , s, r; i <= n; ++i)
{
scanf("%d%d", &s, &r);
v[s].push_back(r);
}
for (int i = ; i <= m; ++i) sort(v[i].rbegin(), v[i].rend());
for (int i = ; i <= m; ++i) q.push(i);
int res = , tmp = ;
for (int i = ; ; ++i)
{
if (q.empty()) break;
for (int j = , len = q.size(); j <= len; ++j)
{
int top = q.front(); q.pop();
tmp -= tot[top];
if (v[top].size() < i)
continue;
tot[top] += v[top][i - ];
if (tot[top] <= ) continue;
tmp += tot[top];
q.push(top);
}
res = max(res, tmp);
}
printf("%d\n", res);
}
return ;
}
D. Maximum Diameter Graph
Solved.
题意:
给出一个n,和每个点最大的度数,构造一棵树,使得每个点的度数不超过最大度数,并且直径最长
思路:
如果所有点的度数之和小于$2 * (n - 1)$ 那么就不可以构造
否则将所有度数$>= 2的点放到直径上,再两边添加一个度为1的点(如果有)$
$剩下的点就连到这条直径上还有度数剩余的点上$
n给的好小,好怀疑自己的做法,当时。
#include <bits/stdc++.h>
using namespace std; #define N 510
int n, a[N];
vector <int> l, r; int main()
{
while (scanf("%d", &n) != EOF)
{
int sum = ;
l.clear(), r.clear();
for (int i = ; i <= n; ++i)
{
scanf("%d", a + i);
sum += a[i];
if (a[i] > ) l.push_back(i);
else r.push_back(i);
}
if (sum < * (n - )) puts("NO");
else
{
if (!r.empty()) l.insert(l.begin(), r.end()[-]), r.pop_back();
if (!r.empty()) l.push_back(r.end()[-]), r.pop_back();
printf("YES %d\n", (int)l.size() - );
printf("%d\n", n - );
for (int i = , len = l.size(); i < len; ++i) printf("%d %d\n", l[i], l[i - ]), --a[l[i]], --a[l[i- ]];
for (int i = , j = , len1 = l.size(), len2 = r.size(); i < len2; ++i)
{
while (a[l[j]] == ) ++j;
--a[l[j]];
printf("%d %d\n", r[i], l[j]);
}
}
}
return ;
}
E. Increasing Frequency
Solved.
题意:
给出一个n个数,可以选取一段$[l, r],$ 使得区间内所有数都$+k$
求最多进行一次这样的操作,使得最后$a_i == c$的个数最多
求这个最多的个数
思路:
显然一个区间的贡献这个区间内相同数字最大的个数加上区间外c的个数,然后这样区间枚举就是$O(n^2)$
我们可以考虑,枚举$a_i$ 即要把哪些数字变成$c$
那么这时候,所有不是$c也不是a_i 的数字就没有用$ 不妨把它们单独拿出来考虑(类似于虚树思想)
假设$L[i], R[i] 表i左边的c的个数 和 i 右边的c的个数$
那么我假设序列中有$x个a(a 为枚举的a_i)$
$L[1], R[1], ... L[x], R[x]$
我们$需要找一个以后 x, y 使得 R[y] + (y - x + 1) + L[x] 最大$
$那么可以枚举x ,然后即找一个最大的 (y - x + 1) + R[y]$
这个可以用线段树维护。
发现常数项是递增的,建树的时候就可以给它,每次更新的时候,相当于后面的每一个都减一
#include <bits/stdc++.h>
using namespace std; #define N 500010
int n, c, a[N], dpl[N], dpr[N];
vector <int> v[N]; namespace SEG
{
int Max[N << ], lazy[N << ];
void pushup(int id) { Max[id] = max(Max[id << ], Max[id << | ]); }
void build(int now, int id, int l, int r)
{
Max[id] = lazy[id] = ;
if (l == r)
{
Max[id] = l + dpr[v[now][l - ]];
return;
}
int mid = (l + r) >> ;
build(now, id << , l, mid);
build(now, id << | , mid + , r);
pushup(id);
}
void pushdown(int id)
{
if (!lazy[id]) return;
lazy[id << ] += lazy[id];
Max[id << ] += lazy[id];
lazy[id << | ] += lazy[id];
Max[id << | ] += lazy[id];
lazy[id] = ;
}
void update(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr)
{
--Max[id];
--lazy[id];
return;
}
int mid = (l + r) >> ;
pushdown(id);
if (ql <= mid) update(id << , l, mid, ql, qr);
if (qr > mid) update(id << | , mid + , r, ql, qr);
pushup(id);
}
int query(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr) return Max[id];
int mid = (l + r) >> ;
pushdown(id);
int res = ;
if (ql <= mid) res = max(res, query(id << , l, mid, ql, qr));
if (qr > mid) res = max(res, query(id << | , mid + , r, ql, qr));
return res;
}
} void init()
{
for (int i = ; i <= ; ++i) v[i].clear();
} int main()
{
while (scanf("%d%d", &n, &c) != EOF)
{
init();
for (int i = ; i <= n; ++i) scanf("%d", a + i), v[a[i]].push_back(i);
int tmp = ;
for (int i = ; i <= n; ++i)
{
dpl[i] = tmp;
tmp += a[i] == c;
}
tmp = ;
for (int i = n; i >= ; --i)
{
dpr[i] = tmp;
tmp += a[i] == c;
}
int res = ;
for (int i = ; i <= ; ++i) if (v[i].size())
{
int len = v[i].size();
SEG::build(i, , , len);
for (int j = ; j < len; ++j)
{
res = max(res, dpl[v[i][j]] + SEG::query(, , len, j + , len));
SEG::update(, , len, j + , len);
}
}
printf("%d\n", res);
}
return ;
}
F. Speed Dial
Upsolved.
题意:
给出一串电话号码,以及需要拨打的次数,有k个快捷键可以快速拨出一串号码,该号码可不在给出的电话号码中
求最少的按键次数(快捷键不算一次按键)
思路:
在$Trie树上DP$
$dp[x][rem][fa] 表示到第x个节点,剩余rem次快捷键使用,上一次使用快捷键的节点为fa$
$dp2[x][rem][fa][i] 前面含义相同,i 表示第i个子节点$
$dp[x][rem][fa] = min(dp[x][rem][fa], dp[x][rem - 1][x])$
$dp2[x][rem][fa][i] = min(dp2[x][rem][fa][i], dp2[x][rem - j][fa][i + 1] + dp[x[i]][j][fa])$
$dp[x][rem][fa] = min(dp[x][rem][fa], dp2[x][rem][fa][0] + cnt * len)$
#include <bits/stdc++.h>
using namespace std; #define INF 0x3f3f3f3f
#define N 510
int n, k, m;
struct TRIE
{
int cnt, deep;
int son[];
void init()
{
cnt = ;
memset(son, -, sizeof son);
}
}a[N]; int pos; char s[N]; int tot;
void insert()
{
scanf("%s%d", s, &tot);
int now = ;
for (int i = , len = strlen(s); i < len; ++i)
{
int to = s[i] - '';
if (a[now].son[to] == -)
{
a[now].son[to] = ++pos;
a[pos].init();
a[pos].deep = a[now].deep + ;
}
now = a[now].son[to];
}
a[now].cnt += tot;
} int dp[N][][N];
int dp2[N][][N][];
int DFS(int x, int rem, int fa)
{
if (dp[x][rem][fa] != -) return dp[x][rem][fa];
dp[x][rem][fa] = INF;
if (rem) dp[x][rem][fa] = DFS(x, rem - , x);
vector <int> G;
for (int i = ; i < ; ++i) if (a[x].son[i] != -)
G.push_back(a[x].son[i]);
dp2[x][rem][fa][G.size()] = ;
for (int i = (int)G.size() - ; i >= ; --i)
{
for (int j = ; j <= rem; ++j)
dp2[x][rem][fa][i] = min(dp2[x][rem][fa][i], dp2[x][rem - j][fa][i + ] + DFS(G[i], j, fa));
}
dp[x][rem][fa] = min(dp[x][rem][fa], dp2[x][rem][fa][] + a[x].cnt * (a[x].deep - a[fa].deep));
return dp[x][rem][fa];
} void init()
{
a[].init();
pos = ;
a[].deep = ;
} int main()
{
while (scanf("%d%d", &n, &k) != EOF)
{
init();
for (int i = ; i <= n; ++i) insert();
memset(dp, -, sizeof dp);
memset(dp2, 0x3f, sizeof dp2);
printf("%d\n", DFS(, k, ));
}
return ;
}
G. Petya and Graph
Unsolved.
Educational Codeforces Round 55 (Rated for Div. 2) Solution的更多相关文章
- Educational Codeforces Round 55 (Rated for Div. 2) C. Multi-Subject Competition 【vector 预处理优化】
		
传送门:http://codeforces.com/contest/1082/problem/C C. Multi-Subject Competition time limit per test 2 ...
 - Educational Codeforces Round 55 (Rated for Div. 2)    A/B/C/D
		
http://codeforces.com/contest/1082/problem/A WA数发,因为默认为x<y = = 分情况讨论,直达 or x->1->y or x-& ...
 - Educational Codeforces Round 55 (Rated for Div. 2) B. Vova and Trophies 【贪心 】
		
传送门:http://codeforces.com/contest/1082/problem/B B. Vova and Trophies time limit per test 2 seconds ...
 - Codeforces 1082 C. Multi-Subject Competition-有点意思 (Educational Codeforces Round 55 (Rated for Div. 2))
		
C. Multi-Subject Competition time limit per test 2 seconds memory limit per test 256 megabytes input ...
 - Codeforces 1082 A. Vasya and Book-题意 (Educational Codeforces Round 55 (Rated for Div. 2))
		
A. Vasya and Book time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
 - Educational Codeforces Round 55 (Rated for Div. 2):E. Increasing Frequency
		
E. Increasing Frequency 题目链接:https://codeforces.com/contest/1082/problem/E 题意: 给出n个数以及一个c,现在可以对一个区间上 ...
 - Educational Codeforces Round 55 (Rated for Div. 2):D. Maximum Diameter Graph
		
D. Maximum Diameter Graph 题目链接:https://codeforces.com/contest/1082/problem/D 题意: 给出n个点的最大入度数,要求添加边构成 ...
 - Educational Codeforces Round 55 (Rated for Div. 2):C. Multi-Subject Competition
		
C. Multi-Subject Competition 题目链接:https://codeforces.com/contest/1082/problem/C 题意: 给出n个信息,每个信息包含专业编 ...
 - Educational Codeforces Round 55 (Rated for Div. 2)E
		
题:https://codeforces.com/contest/1082/problem/E 题意:给出n个数和一个数c,只能操作一次将[L,R]之间的数+任意数,问最后该序列中能存在最多多少个c ...
 
随机推荐
- 多线程模块:threading
			
threading 常见用法: (1) 在 thread 中,我们是通过 thread.start_new_thread(function, args) 来开启一个线程,接收一个函数和该函数的参数,函 ...
 - VS2015编译OpenSSL1.0.2源码
			
更多详细信息http://blog.csdn.net/YAOJINGKAO/article/details/53041165?locationNum=10&fps=1 1.下载安装编译必须的A ...
 - Apache nutch1.5 & Apache solr3.6
			
第1章引言 1.1nutch和solr Nutch 是一个开源的.Java 实现的搜索引擎.它提供了我们运行自己的搜索引擎所需的全部工具. Solr 拥有像 web-services API 的独立的 ...
 - C++类中的static数据成员,static成员函数
			
C++类中谈到static,我们可以在类中定义static成员,static成员函数!C++primer里面讲过:static成员它不像普通的数据成员,static数据成员独立于该类的任意对象而存在, ...
 - MUI  Hbuilder设置模拟器运行APP项目
			
1 安装hbuilder和夜神模拟器 2 hbuilder 新建app项目 3 hbuilder:运行-> 设置web服务器->Hbuilder 第三方安卓模拟器端口:62001 4 运 ...
 - android框架---->下沉文字Titanic的使用
			
Titanic is a simple illusion obtained by applying an animated translation on the TextView TextPaint ...
 - MQTT的学习研究(十)【转】mosquitto——一个开源的mqtt代理
			
MQTT(MQ Telemetry Transport),消息队列遥测传输协议,轻量级的发布/订阅协议,适用于一些条件比较苛刻的环境,进行低带宽.不可靠或间歇性的通信.值得一提的是mqtt提供三种不同 ...
 - gvim编辑器_vimrc文件
			
set nocompatiblesource $VIMRUNTIME/vimrc_example.vimsource $VIMRUNTIME/mswin.vimbehave mswin set dif ...
 - 动态设置progressBar的进度
			
progressDrawable = this.getResources().getDrawable(R.drawable.image); progressDrawable.setBounds(mSe ...
 - WCF(一) 创建第一个WCF
			
定义服务契约-创建宿主程序-创建客户端程序访问服务 namespace HelloService { /// <summary> /// 服务契约 /// </summary> ...