Codeforces Round #433 div2 C,D 题 题解
2017-09-08 16:27
330 查看
CF – 835A 传送门
//题意: 给定n,k. 重新安排一个时间表, 范围是(k+1,k+n), 你需要计算的是一个新的时刻表, 使得res = (第一个时间 -1)*a[1] + (第二个时间 -2)*a[2] + … 要最小. a[1] - a
是题目中给出的.
//思路: 也是比较简单的一道题, 我们贪心的选择对于输入的cost越大的, 我们就从(k+1, k+n)中选出一个最接近对应这个cost的pos的数给它(这样减出来的值很小, 再一乘也就比较小了). 那么这样选出来的序列是最优的. (这个贪心的策略一定是对的, 你可以假设cost稍微变化下, 但是最后发现还是这样就是最优的). 那么如何在(k+1,k+n)中找到对应最接近的pos了, 并且要保证是按val值从大到小排好的. 那么自然就想到用优先队列维护. 对于当前k+i所有小于它的pos, 全部推入队列. 然后取出对首, 对首这个位置就应该是当前的k+i值. 然后顺便计算res即可. 细节请看代码
AC Code
CF - 835B 传送门
//题意: 有n个人, m条航班, 问让这n个人一起在首都0工作最少k天, 并最后都回家的最小花费(坐飞机去或回家, 到首都的当天不能算为工作日). 如果不可能就输出-1.
//思路: 先处理出每一个可以使所有人都到首都的天数的最优值. 再处理出每一个可以使所有人都回到家的天数的最优值. 然后扫一遍判断一下长度为k+1的前后缀的值的关系. 更新答案即可.
注意一点的就是: 处理完了前或后缀, 需要更新每一个天数的最小值. (前缀的思想!) 还有k的范围, 所以数组需要开大点! 细节请看代码.
AC Code
//题意: 给定n,k. 重新安排一个时间表, 范围是(k+1,k+n), 你需要计算的是一个新的时刻表, 使得res = (第一个时间 -1)*a[1] + (第二个时间 -2)*a[2] + … 要最小. a[1] - a
是题目中给出的.
//思路: 也是比较简单的一道题, 我们贪心的选择对于输入的cost越大的, 我们就从(k+1, k+n)中选出一个最接近对应这个cost的pos的数给它(这样减出来的值很小, 再一乘也就比较小了). 那么这样选出来的序列是最优的. (这个贪心的策略一定是对的, 你可以假设cost稍微变化下, 但是最后发现还是这样就是最优的). 那么如何在(k+1,k+n)中找到对应最接近的pos了, 并且要保证是按val值从大到小排好的. 那么自然就想到用优先队列维护. 对于当前k+i所有小于它的pos, 全部推入队列. 然后取出对首, 对首这个位置就应该是当前的k+i值. 然后顺便计算res即可. 细节请看代码
AC Code
/** @Cain*/ const int maxn = 3e5+5; int cas=1; int ans[maxn]; struct node { int val,pos; bool operator < (const node& a) const { return a.val > val; } }s[maxn]; void solve() { int n,k; scanf("%d%d",&n,&k); priority_queue<node >q; for(int i=1;i<=n;i++){ scanf("%d",&s[i].val); s[i].pos = i; } ll res = 0; int cnt = 1; //printf("%d\n",q.top().val); for(int i=1;i<=n;i++){ while(cnt<=n && s[cnt].pos<=i+k){ q.push(s[cnt]); cnt++; } node tmp = q.top(); q.pop(); ans[tmp.pos] = i+k; res += 1ll*(i+k - tmp.pos)*tmp.val; } printf("%lld\n",res); for(int i=1;i<=n;i++){ printf("%d%c",ans[i],i==n?'\n':' '); } }
CF - 835B 传送门
//题意: 有n个人, m条航班, 问让这n个人一起在首都0工作最少k天, 并最后都回家的最小花费(坐飞机去或回家, 到首都的当天不能算为工作日). 如果不可能就输出-1.
//思路: 先处理出每一个可以使所有人都到首都的天数的最优值. 再处理出每一个可以使所有人都回到家的天数的最优值. 然后扫一遍判断一下长度为k+1的前后缀的值的关系. 更新答案即可.
注意一点的就是: 处理完了前或后缀, 需要更新每一个天数的最小值. (前缀的思想!) 还有k的范围, 所以数组需要开大点! 细节请看代码.
AC Code
/** @Cain*/ const int maxn = 1e6+5; int cas=1; struct node { int d,s,e; ll w; bool operator < (const node& a) const { return d<a.d; } }s[maxn]; ll dp1[2*maxn],dp2[2*maxn]; ll vis[maxn]; void solve() { int n,m,k; while(~scanf("%d%d%d",&n,&m,&k)){ Fill(dp1,0); Fill(dp2,0); int cnt1 = 0,cnt2 = 0 ; int maxx = 0; for(int i=1;i<=m;i++){ scanf("%d%d%d%lld",&s[i].d,&s[i].s,&s[i].e,&s[i].w); maxx = max(maxx,s[i].d); } sort(s+1,s+1+m); int num = 0; ll sum = 0; Fill(vis,0); for(int i=1;i<=m;i++){ //处理前面 if(s[i].s == 0) continue; if(!vis[s[i].s]){ num++; vis[s[i].s] = s[i].w; sum += s[i].w; } else if(vis[s[i].s] > s[i].w){ sum -= vis[s[i].s]; sum += s[i].w; vis[s[i].s] = s[i].w; } if(num == n){ //n个人都到了首都. dp1[s[i].d] = sum; } } num = 0 ; sum = 0; Fill(vis,0); for(int i=m;i>=1;i--){ //处理后面 if(s[i].e == 0) continue; if(!vis[s[i].e]){ num++; vis[s[i].e] = s[i].w; sum += s[i].w; } else if(vis[s[i].e] > s[i].w){ sum -= vis[s[i].e]; sum += s[i].w; vis[s[i].e] = s[i].w; } if(num == n){ //n个人都回到了家 dp2[s[i].d] = sum; } } for(int i=1;i<=maxx;i++){ //前缀的思想 if(!dp1[i]) dp1[i] = dp1[i-1]; else if(dp1[i-1]) dp1[i] = min(dp1[i],dp1[i-1]); //如果第i-1天就全部到达了首都, 那么第i天肯定也全部都到了首都.需要更新一个最优值. } for(int i=maxx;i>=1;i--){ if(!dp2[i]) dp2[i] = dp2[i+1]; else if(dp2[i+1]) dp2[i] = min(dp2[i],dp2[i+1]); //和前面的思想一样的. } ll res = INF; for(int i=1;i<=maxx;i++){ if(dp1[i] && dp2[i+k+1]) res = min(res,dp1[i]+dp2[i+k+1]); //每次判断一个长度为k的区间范围.同时更新答案. } if(res == INF) printf("-1\n"); else printf("%lld\n",res); } }
相关文章推荐
- Codeforces Round #433 (Div. 2 D. Jury Meeting 二分
- Codeforces Round #433 (Div. 2 D. Jury Meeting 二分
- Codeforces Round #433 (Div. 2) 题解
- Codeforces Round #433 Div. 2 C - Planning 模拟
- Codeforces Round #433 (Div. 2) Jury Meeting(贪心)
- Codeforces Round #433 (Div. 2 D. Jury Meeting 二分
- Jury Meeting Codeforces Round #433 (Div. 2, based on Olympiad of Metropolises)(贪心,预处理?)
- Codeforces Round #433 (Div. 2) D. Jury Meeting
- Codeforces Round #433 (Div. 2 D. Jury Meeting 二分
- Codeforces Round #433 (Div. 2 D. Jury Meeting 二分
- Codeforces Round #433 (Div. 1) B Jury Meeting(思维)
- Codeforces Round #433 (Div. 2 D. Jury Meeting 二分
- Codeforces Round #433 (Div. 2) Planning (贪心+并查集)
- Codeforces Round #433 (Div. 2 D. Jury Meeting 二分
- Codeforces Round #433 (Div. 2) A.Fraction(暴力)
- Codeforces Round #433 (Div. 2 D. Jury Meeting 二分
- Codeforces Round #433 (Div. 2 D. Jury Meeting 二分
- Codeforces Round #433 (Div. 2 D. Jury Meeting 二分
- Codeforces Round #433 (Div. 2 D. Jury Meeting 二分
- Codeforces Round #433 (Div. 2 D. Jury Meeting 二分