杭二集训 dierti (CF GYM 100016F)
2018-01-09 20:59
316 查看
标签:贪心,DP
2.1 backgrounds
小O是一个很萌很萌的女孩子
2.2 content
有一段时间,小O对保龄球十分感兴趣,她特地去研究了一下保龄球的 规则。 一场比赛一共有n轮, 在每轮的一开始有10个瓶子,每一轮小O有两次扔球机会。一轮结束 后,瓶子会被重置。 如果小O某一轮中击倒了10个瓶子,称为“奥义”。 特别的,如果小O第一次扔球就击倒了10个瓶子,称为“全给”(不再 称为“奥义”)。 另外,如果小O在第n轮中打出了“全给”,那么她可以获得额外的一 轮。(只能获得一次) 最后的分数是这么计算的: 每次扔球的基础分是该次击倒的瓶子数目。 如果上一次是“全给”,则小O额外获得与这轮基础分相同的奖励分。 如果上一次是“奥义”,则小O额外获得与这轮的第一次扔球的基础分 相同的奖励分。 最后的总分是把所有分加起来。 现在给出小O的比赛情况,她现在想知道,通过重新排列每轮的顺序能 获得的最大得分是多少。 提醒:有奖励轮时第n轮必须是“全给”,重排后也是一样。
2.3 input format
第一行一个正整数n,表示预定的轮数。 接下来n行,每行两个正整数ai,bi,表示小O第i轮两次扔球分别击倒 的瓶子个数。 特别的,如果an = 10,则还有一行输入,表示奖励轮中小O两次扔球 分别击倒的瓶子个数。
2.4 output format
一行一个整数,表示最大可能得分。
2.5 sample input
2
3 7
10 0
5 2
2.6 sample output
44
2.7 sample explanation
将第一轮和第三轮互换一下,可以得到最大分数。
2.8 constraints 对于30%的数据,n ≤ 9 对于100%的数据,n ≤ 50,0 ≤ ai + bi ≤ 10
好多人随机化然后AC了,逃)
我第一次听到出题人被骂sb的(删去)(不是我)
首先把所有 全给 接成一串,这样除了最后一个 全给 所有的 全给 都提供了10的收益
枚举一下最后一个 全给 后面接的是什么,可能有(1) 正常 (2) 奥义 (3) 奥义 + 正常 3种情况
把剩下的 正常 放在所有 全给 前面,再把 奥义 向序列中插入
因为不会改变 全给 获得的收益,只会得到一个第一投分数的收益,直接贪心就行
注意如果给了n+1行的话就必须保证序列倒数第二个是 全给 ,所以不存在(3)的情况
标程
题目
题目传送门2.1 backgrounds
小O是一个很萌很萌的女孩子
2.2 content
有一段时间,小O对保龄球十分感兴趣,她特地去研究了一下保龄球的 规则。 一场比赛一共有n轮, 在每轮的一开始有10个瓶子,每一轮小O有两次扔球机会。一轮结束 后,瓶子会被重置。 如果小O某一轮中击倒了10个瓶子,称为“奥义”。 特别的,如果小O第一次扔球就击倒了10个瓶子,称为“全给”(不再 称为“奥义”)。 另外,如果小O在第n轮中打出了“全给”,那么她可以获得额外的一 轮。(只能获得一次) 最后的分数是这么计算的: 每次扔球的基础分是该次击倒的瓶子数目。 如果上一次是“全给”,则小O额外获得与这轮基础分相同的奖励分。 如果上一次是“奥义”,则小O额外获得与这轮的第一次扔球的基础分 相同的奖励分。 最后的总分是把所有分加起来。 现在给出小O的比赛情况,她现在想知道,通过重新排列每轮的顺序能 获得的最大得分是多少。 提醒:有奖励轮时第n轮必须是“全给”,重排后也是一样。
2.3 input format
第一行一个正整数n,表示预定的轮数。 接下来n行,每行两个正整数ai,bi,表示小O第i轮两次扔球分别击倒 的瓶子个数。 特别的,如果an = 10,则还有一行输入,表示奖励轮中小O两次扔球 分别击倒的瓶子个数。
2.4 output format
一行一个整数,表示最大可能得分。
2.5 sample input
2
3 7
10 0
5 2
2.6 sample output
44
2.7 sample explanation
将第一轮和第三轮互换一下,可以得到最大分数。
2.8 constraints 对于30%的数据,n ≤ 9 对于100%的数据,n ≤ 50,0 ≤ ai + bi ≤ 10
分析
直接粘题解了,贪心的思路不错,但是题目放在OI比赛里真的不好好多人随机化然后AC了,逃)
我第一次听到出题人被骂sb的(删去)(不是我)
首先把所有 全给 接成一串,这样除了最后一个 全给 所有的 全给 都提供了10的收益
枚举一下最后一个 全给 后面接的是什么,可能有(1) 正常 (2) 奥义 (3) 奥义 + 正常 3种情况
把剩下的 正常 放在所有 全给 前面,再把 奥义 向序列中插入
因为不会改变 全给 获得的收益,只会得到一个第一投分数的收益,直接贪心就行
注意如果给了n+1行的话就必须保证序列倒数第二个是 全给 ,所以不存在(3)的情况
code
随机化#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<ctime> #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,a,b) for(int i=a;i>=b;i--) #define ll long long #define mem(x,num) memset(x,num,sizeof x) #define reg(x) for(int i=last[x];i;i=e[i].next) using namespace std; inline ll read() { ll f=1,x=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=56; int n; bool flag=false; pair<int,int>a[maxn]; int calc(){ if((flag)&&(a[n-1].first!=10))return -1; int ans=0,p=1,q=1; rep(i,1,n){ ans+=a[i].first*p+a[i].second*q; if(a[i].first==10)p=q=2; else if(a[i].first+a[i].second==10)p=2,q=1; else p=q=1; } return ans; } int main() { srand(time(0)); n=read(); rep(i,1,n)a[i].first=read(),a[i].second=read(); if(a .first==10){ n++;flag=true; a .first=read(),a .second=read(); } int T=1000000,ans=calc(); while(T--){ int p=rand()%n+1,q=rand()%n+1; swap(a[p],a[q]); int ths=calc(); if(ths>=ans)ans=ths;else swap(a[p],a[q]); } cout<<ans<<endl; return 0; }
标程
#include <bits/stdc++.h> using namespace std; int N, n, a, b; int strick; vector<int>spare, normal; int maxsum[20]; int base; int ans, now; int main() { freopen("dierti10.in","r",stdin); freopen("dierti10.out","w",stdout); scanf("%d", &N); while (scanf("%d%d", &a, &b) != EOF) { n++; base += a + b; if (a + b != 10) { normal.push_back(a); maxsum[a] = max(maxsum[a], a + b); } else if (a != 10) { spare.push_back(a); } else { strick++; } } if (strick) { base += (strick - 1) * 10; } sort(spare.begin(), spare.end()); reverse(spare.begin(), spare.end()); for (int i = 0; i < int(normal.size()); i++) { now = strick ? maxsum[normal[i]] : 0; priority_queue<int>q; for (int j = 1; j <= strick; j++) { q.push(10); } for (int j = 0; j < int(normal.size()); j++) { if (!strick || j != i) { q.push(normal[j]); } } for (int j = 0; j < int(spare.size()); j++) { if (!q.empty()) { now += q.top(); q.pop(); } q.push(spare[j]); } ans = max(ans, now); } for (int i = 0; i < int(spare.size()); i++) { now = strick ? 10 : 0; priority_queue<int>q; for (int j = 1; j <= strick; j++) { q.push(10); } for (int j = 0; j < int(normal.size()); j++) { q.push(normal[j]); } q.push(spare[i]); for (int j = 0; j < int(spare.size()); j++) { if (j != i) { if (!q.empty()) { now += q.top(); q.pop(); } q.push(spare[j]); } } ans = max(ans, now); } if (n == N) { for (int i = 0; i < int(normal.size()); i++) { for (int k = 0; k < int(spare.size()); k++) { now = normal[i]; now += strick ? 10 : 0; priority_queue<int>q; for (int j = 1; j <= strick; j++) { q.push(10); } for (int j = 0; j < int(normal.size()); j++) { if (j != i) { q.push(normal[j]); } } q.push(spare[k]); for (int j = 0; j < int(spare.size()); j++) { if (j != k) { if (!q.empty()) { now += q.top(); q.pop(); } q.push(spare[j]); } } ans = max(ans, now); if (now == 37) { printf("%d %d\n", normal[i], spare[k]); } } } } printf("%d\n", ans + base); return 0; }
相关文章推荐
- 杭二集训 diyiti (CF GYM 101597A)
- 杭二集训 电报
- 【CF Gym 100637K】 Microcircuits 【DP】【环上n个点,问不相交的连k条线的方案数】
- [CF Gym 100372C] Sergey and array
- 杭二集训 三明治
- [CF Gym 100827C] Containment [2014-2015 ACM-ICPC Pacific Northwest Regional Contest C]
- cf/Codeforces Gym 100548F Color (容斥原理)
- CF - gym - Samara University ACM ICPC 2016-2017 Quarterfinal Qualification Contest --- G
- [CF Gym 100372E] Sergey’s game
- CF 678C 暑假集训13(gcd,lcm)
- [CF Gym 100827E] Hill Number [2014-2015 ACM-ICPC Pacific Northwest Regional Contest E]
- [CF Gym 100827F] Knights [2014-2015 ACM-ICPC Pacific Northwest Regional Contest F]
- [CFgym]2015-2016 ACM-ICPC Pacific Northwest Regional Contest小结
- [CF Gym 100827K] Towers [2014-2015 ACM-ICPC Pacific Northwest Regional Contest K]
- CF 676A 暑假集训13
- Cookie Selection - CF_GYM, 100112C 中位数动态查找
- CF Gym 100637B Lunch(拆分子问题)
- [bzoj4928][SDOI省队集训2017]dierti
- uvalive7040 / cf gym 100548 Color(2014西安区域赛F题)
- 杭二集训 disanti (51Nod 1667 概率好题)