背景背景 机房里的人都十分认真地在编程,但总有一些人会偷偷玩游戏。。。。。。 问题描述问题描述
问题描述问题描述 XY 经常在机房里偷偷玩游戏,于是他也经常被CJH 教练批评。但屡次的批评一点作用也
没有,你看他又开始玩起了游戏。 这次XY 可碰上难题了,因为据可靠的线报CJH 教练在不久后就回来机房,但XY 需要完
成N 个任务才能将这个游戏通关。 每个任务完成时限T,就是这个任务必须在时间T 之前完成(你可以认为游戏刚开始的时
间为1),还有完成这个任务XY 可以获得一定的奖励W。由于XY 娴熟的技术以及任务的简
单,他可以在一个单位时间将任务完成。 XY 想要在CJH 教练到来之前将任务全部完成,同时他也想获得最多的奖励。这个他本来
可以编程自己完成的,但是为了能马上将游戏通关,他需要全神贯注进去。于是他没有空编
程计算,于是他希望你能帮助他将问题的答案计算出来。 输入格式输入格式
输入格式输入格式 输入数据第一行有一个整数N ,表示需要完成的任务数目; 接下来N  行,每行两个整数T,W  (中间用一个空格隔开),分别表示完成这个任务的最 后期限和完成这个任务后获得的奖励。 输出格式输出格式
输出格式输出格式 输出数据有且仅有一行,只包含一个整数S,表示最多获得的奖励。 样例输入输出样例输入输出
样例输入输出样例输入输出 Sample #1
game.in                                    game.out
2                                          5
1 5
1 4 Sample #2
game.in                                    game.out
5                                          15
2 3
1 2
4 5
1 3
3 4 样例解释样例解释
样例解释样例解释 对于样例2 XY 可以选择完成任务1,3,4 和5,这样他可以获得奖励15。 数据规模数据规模
数据规模数据规模 对于10%的数据,N≤100,Ti≤100,Wi≤2000;
对于30%的数据,N≤1000,Ti≤5000,Wi≤2000;
对于50%的数据,N≤10000,Ti≤20000,Wi≤2000;
对于100%的数据,N≤200000,Ti≤200000,Wi≤2000 。 时间限制时间限制
时间限制时间限制
1s 

这道题一看感觉是一道简单题,就随便想了一个贪心策略来解,结果悲剧地WA0。这是个血的教训啊。听上去讲解的同学,他们的贪心策略都是证明过的。

唉。。。其实考试的时候时间也没有那么紧张,证明一下也何尝不好呢??
我的贪心策略就是,每一时刻选择一个期限为当前时间的最大价值的任务来做。其实这个反例太多,只是我没有去想过。
如四个任务的时间 1 1 2 2,价值1 1 100 100,最大价值为200而不是101。
这道题的好方法有几个。
梁旭罡:
使用了两个接近正解的贪心策略,每次从中取出较小值(这两个贪心策略都是过贪的),结果AC了。这个值得学习。
program seat;
constf1=2;f2=3;
varex,jj,jz:array[1..2,1..2]of int64;n,m:longint;procedure init;
beginassign(input,'seat.in');reset(input);assign(output,'seat.out');rewrite(output);
end;function f(n:int64):int64;
vari:longint;nn:int64;p:boolean;
beginjz[1,1]:=0;jz[1,2]:=1;jz[2,1]:=1;jz[2,2]:=1;p:=true;nn:=n-2;while nn>0 do beginif nn and 1=1  then beginif not p then beginex[1,1]:=(jj[1,1]*jz[1,1]+jj[1,2]*jz[2,1])mod m;ex[1,2]:=(jj[1,1]*jz[1,2]+jj[1,2]*jz[2,2])mod m;ex[2,1]:=(jj[2,1]*jz[1,1]+jj[2,2]*jz[2,1])mod m;ex[2,2]:=(jj[2,1]*jz[1,2]+jj[2,2]*jz[2,2])mod m;jj:=ex;endelse begin jj:=jz;p:=false end;end;ex[1,1]:=(jz[1,1]*jz[1,1]+jz[1,2]*jz[2,1])mod m;ex[1,2]:=(jz[1,1]*jz[1,2]+jz[1,2]*jz[2,2])mod m;ex[2,1]:=(jz[2,1]*jz[1,1]+jz[2,2]*jz[2,1])mod m;ex[2,2]:=(jz[2,1]*jz[1,2]+jz[2,2]*jz[2,2])mod m;jz:=ex;nn:=nn shr 1;end;case n of1:begin f:=f1;exit;end;2:begin f:=f2;;exit;end;end;f:=(f1*jj[1,2]+f2*jj[2,2])mod m;
end;procedure main;
vart,i:longint;
beginreadln(t,m);for i:=1 to t do beginreadln(n);writeln(f(n));end;close(output);
end;begininit;main;
end.

汪维正+彭靖田

贪心+堆优化
我打出来了这个。
思路:因为正向贪容易推出反例来,因此考虑到了反向来贪心,这是个好思路,值得学习呀。
就是从最大的时间到最小的时间,最后时刻,只能够选择期限为这个时刻的任务,否则就没得做了,因此做这个时刻价值最大的任务,用反证法,如果做其他的任务,解只可能小于或等于最优解。
剩下来的任务保留,或不做,或在前面时刻做,每一个时刻都把期限为当前时刻的任务加入进来,选择最优的,最优的选择同上。
因此考虑使用堆优化。维护一个大根堆。
(常常易忘记的del()函数的返回值)
这个思路不难,也易证明。这个反向来贪心的思路不错!!还有以后时间不紧的情况下一定要证明自己的策略!!
//用堆的贪心方法 #include <cstdio>
#include <cstdlib>
long n;
struct node
{long t;long a;
};
const long oo = 0x7fff0000;
long heap[200002];
long size = 0;
long start[200002];
node task[200002];
long ans = 0;void swap(long a,long b)
{long tmp = heap[a];heap[a] = heap[b];heap[b] = tmp;
}void adjust_down(long l)
{while((l<<=1)<size+1){if (l+1<=size&&task[heap[l+1]].a>task[heap[l]].a)l++;if (task[heap[l>>1]].a<task[heap[l]].a) swap(l>>1,l);else break;}
}void adjust_up(long l)
{while (l>1){if (task[heap[l]].a>task[heap[l>>1]].a)swap(l,l>>1);else break;l >>= 1;}
}long del()
{if (size<=0) return -1;long tmp = heap[1];heap[1] = heap[size];size--;adjust_down(1);return tmp;
}void insert(long l)
{size++;heap[size] = l;adjust_up(size);
}int bigger(const void *a,const void* b)
{long aa = *(long*)a;long bb = *(long*)b;if (aa>bb)return 1;else if (aa==bb)return 0;return -1;
}int main()
{freopen("game.in","r",stdin);freopen("game.out","w",stdout);scanf("%ld",&n);for (long i=1;i<n+1;i++){scanf("%ld%ld",&task[i].t,&task[i].a);}qsort(task+1,n,sizeof(node),&bigger);for (long i=n;i>0;i--){if (start[task[i].t]==0)start[task[i].t]=i;}long index = n;for (long i=task[index].t;i>0;i--){while (index>=0&&task[index].t==i){insert(index);index--;}long tmp = del();if (tmp>0)ans += task[tmp].a;}printf("%ld",ans);
}

刘德恩:

贪心+并查集
代码比较简短,思路比较巧妙。
仍然是贪心。
每次选择价值最大的任务,如果能做(接下来讨论)就做,不能做则放弃并选择次优。
能做即从1时刻到任务的最后时刻有空可以做,
做一个任务,一定要完成,则尽量晚,更多的任务可以有时间完成。只会更优,不会更差。
这就可以得到一个朴素的贪心策略。
考虑优化,每扫描到一个任务,要让它能够完成,并时间尽量晚,则应该把它插入1~当前时刻离当前时刻最近的点。
因此想到了区间,又因此想到了集合,并查集。
每次插入点的操作都是一次合并的操作。区间中的点的父亲都指向最左边的那一个点的左边,即最早有空隙的地方。
考虑1~i全部合并的情况,即为所有的i父亲指向0。则1~i不再有空隙了。
这是一个好方法,但是不容易想到。
这个给我启示!!
有时候思路要打开。例如这里,要能从插入的空隙联想到连续区间,再联想到并查集,再联想到父亲指向空隙!!
这思维还是比较跳跃的。。。
我的代码
#include <cstdio>
#include <cstdlib>struct node
{long t;long a;
};long fa[200002];int bigger(const void* a,const void* b)
{node* aa = (node*) a;node* bb = (node*) b;if (aa->a>bb->a)return -1;if (aa->a==bb->a)return 0;return 1;
}long getroot(long a)
{if (fa[a]==a) return a;return fa[a] = getroot(fa[a]);
}void merge(long a,long b)
{fa[getroot(a)] = getroot(b);
}long n;
node task[200002];
long ans = 0;int main()
{freopen("game.in","r",stdin);freopen("game.out","w",stdout);scanf("%ld",&n);long max = 0;for (long i=1;i<n+1;i++){scanf("%ld%ld",&task[i].t,&task[i].a);max >?= task[i].t;}for (long i=0;i<max+1;i++)///一开始写成从0到n了。这是个时间的区间{fa[i] = i; }qsort(task+1,n,sizeof(node),&bigger);for (long i=1;i<n+1;i++) {long ffa = getroot(task[i].t);if (ffa!=0){ans += task[i].a;merge(ffa,ffa-1);//我觉得这句话最具有跳跃性。将父亲设为上一个点,//如果是一个空隙,则指向它,如果是一个连续区间,//则意味着于这个区间合并了并指向最左边}}printf("%ld",ans);
}

刘德恩:

#include<iostream>
#include<cstring>
#include<stdio.h>
using namespace std;struct ee
{int timee,w;
}a[500000];
int n,ans;
int pre[500000];void init()
{freopen("game.in","r",stdin);freopen("game.out","w",stdout);
}int cmp(const void *a,const void *b)
{struct ee *c=(ee *)a;struct ee *d=(ee *)b;if(c->w < d->w) return 1;return -1;
}void readdata()
{scanf("%d\n",&n);int i;for(i=1; i<=n; i++)scanf("%d%d\n",&a[i].timee,&a[i].w);qsort(a+1,n,sizeof(a[1]),cmp);
}int getpre(int x)
{if(x==pre[x]) return pre[x];pre[x]=getpre(pre[x]);return pre[x];
}void merge(int x,int y)
{int f,ff;f=getpre(x);ff=getpre(y);pre[f]=ff;
}void work()
{int i,t,maxx;maxx=0;for(i=1; i<=n; i++)maxx=maxx>a[i].timee ? maxx:a[i].timee;for(i=0; i<=maxx; i++) pre[i]=i;for(i=1; i<=n; i++){t=getpre(a[i].timee);if(t!=0){ans+=a[i].w;merge(t,t-1);}if(getpre(maxx)==0) return;}
}void print()
{printf("%d\n",ans);
}int main()
{init();readdata();work();print();return 0;
}

【游戏通关】解题报告相关推荐

  1. Cdoj 24点游戏之解题报告

    24点游戏 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1252 Descr ...

  2. 百度的年会游戏(解题报告)

    题目来自 计蒜客 百度年会盛况空前,每个部门的年会活动也是非常有趣.某部门的年会中进行了一个有趣的游戏:一张方桌上有四边,每边可以坐一人,每人面前摆放一排长方形木块.我们一次给四边标号,分别为玩家 1 ...

  3. 国王游戏[NOIP2012]解题报告

    在做这道题之前已经预先知道这道题是贪心了,但是贪心的思路却一直没想到,所以看了题解,发现做法还是很神奇的. Step 1 一个定理:        对于一个序列,通过交换其相邻的两个元素,一定可以变成 ...

  4. [LeetCode解题报告] LCP 49. 环形闯关游戏

    [LeetCode解题报告] LCP 49. 环形闯关游戏 一. 题目 1. 题目描述 2. 原题链接 二. 解题报告 1. 思路分析 2. 复杂度分析 3. 代码实现 三. 本题小结 四. 参考链接 ...

  5. 格子游戏 解题报告

    格子游戏  解题报告 v [问题描述] v Alice和Bob玩了一个古老的游戏:首先画一个n * n的点阵(下图n = 3) 接着,他们两个轮流在相邻的点之间画上红边和蓝边: v v v v     ...

  6. 解题报告(八) prufer 序列与 Cayley 公式(ACM / OI)超高质量题解

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  7. 解题报告(一)E、(BZOJ4589)Hard Nim(博弈论 + FWT)

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  8. 解题报告(一)快速沃尔什变换FWT(ACM / OI)超高质量题解

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

  9. Codeforces Round #693 (Div. 3)A~G解题报告

    Codeforces Round #693 (Div. 3)A~G解题报告 A Cards for Friends 原题信息 http://codeforces.com/contest/1472/pr ...

最新文章

  1. 在Flash中利用PCRE正则式漏洞CVE-2015-0318的方法
  2. Arduino作为服务器显示温度,基于Arduino 带LCD显示的电子温度计
  3. 基于Html5的移动端开发框架的研究
  4. 1148 Werewolf - Simple Version (20 分)
  5. windows 访问linux中的mongodb,MongoDB的linux系统下的安装与连接
  6. 測试AtomicInteger与普通int值在多线程下的递增操作
  7. 有做行业站的转行做企业站的吗?
  8. C# 简单日志文本输出
  9. POJ3414 Pots —— BFS + 模拟
  10. 华为招聘产业联盟高级专家、 开发者生态专家
  11. WIN10的永久杜比音效的安装(2021)
  12. 隐藏input的三种方法
  13. win10系统怎样安装/更新独立显卡驱动
  14. BOF算法 基于SIFT+KMeans
  15. linux mplayer rpm,mplayer - movie player for linux
  16. 2019牛客暑期多校训练营(第九场)A——The power of Fibonacci(循环节+中国剩余定理(互质)||广义BM)
  17. 研究生语音识别课程作业记录(三) 非特定人孤立词识别
  18. 学术会议 Rebuttal 模板资料留存
  19. 应用概率统计-第一章 随机事件及其概率
  20. 算法-蓝桥杯习题(3-1)

热门文章

  1. jsonl后缀名是什么意思
  2. Pytorch使用笔记
  3. 解决Maven安装Tomcat插件后,使用出现8080端口占用的问题
  4. 浪潮信息AIStation联合智源研究院 帮助用户灵敏获取本地AI算力
  5. 刚入职就带领公司走上了上云之路
  6. python 通过调取百度接口进行图片OCR文字识别 高识别率
  7. ubuntu 8.04 配置okl4编译环境
  8. oracle用存储返回老师人数,ORACLE复习选编.ppt
  9. Thor与Http catcher介绍
  10. Tcl脚本入门笔记详解(一)