这道题是最优骗分+贪心
原题:
有N (1 <= N <= 1,000,000)个 true 或者false的问题。
其中答案是true的问题的个数有K种可能:t_1, t_2, t_3,..., t_K (0 <= t_i<= N; 0 <= K <= 10,000). 但是我们无法知道具体哪个问题的答案是true或false。
现在Bessie要回答这N个问题,为了在运气最差的情况下答对的题目最多,她必须采取最优策略。比如有6个问题, N=6, k = 2, t_1 = 0, t_2 = 3. 也就是说,这6个问题中,真命题的个数可能是0个,也可能是3个。那么Bessie为了在运气最差的情况答对的问题最多,她可以回答每个问题都是的答案都是false. 可以看出,如果她运气好的话,她能答对6题,但如果运气差的话(即有3到是true的问题),那么她只能答对3题(因为她的回答是6个false)。
因此,Bessie在最差的情况下能答对3题。
我们来看看,如果其它策略,Bessie能否在运气最差的情况下答对的题目超过3题。比如:Bessie的回答是3个true, 3个false. 那么最坏的情况是什么呢?由于Bessie并不知道具体的某问题的答案,可能她全部答错。也就是3个真命题,她的回答是false,而3个假命题,她却刚好回答是yes,这种情况Bessie答对0道题,显然没有上面的策略优。
你的任务是:在采取最优策略下,她在运气最差时,最多能答对几道题
这道题有三种情况
全选false,则采取true最多的可能
全选true,则采取true最少的可能
找出相邻差最大的两个可能,取其差的中间值
情况1情况2不需要证明
情况3证明:
t_i设t_x 和 t_y是相邻的两个t_i(t_x>t_y),FJ可以保证(t_x-t_y)/2个正确答案,他只需选择N-[(t_x+t_y)/2]个正确答案,其余全部选择false
代码:
//Earl_WR 2017.1.19 #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <algorithm> using namespace std; int result=0; int maxx=-1; int n,k; int a[10010],t_f,t_t,t_e; int read() { int x=0,f=1;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; } void in() { n=read();k=read(); for (int i=1;i<=k;i++) { a[i]=read(); } } int main() { //freopen ("test.in","r",stdin); //freopen ("test.out","w",stdout); in(); sort(a+1,a+1+k); t_f=n-a[k]; if (t_f>result)result=t_f; t_t=a[1]; if (t_t>result)result=t_t; for (int i=1;i<=k;i++) { if (a[i+1]-a[i]>maxx) { maxx=a[i+1]-a[i]; } } t_e=maxx/2; if (t_e>result)result=t_e; cout<<result<<endl; return 0; }
下午切了p1828
原题:
Oj上有很多题是联系的,对于某一类型的题目,必须要把基础的题目做完,再总结一段时间,才能够去切不水的题目。
在noip最后一周,老师布置了很多很多的题目来切。
为了更好的备考,为了更好的打好基础,老师规定切题的规则如下:
对于老师布置的某项基础作业X,神犇必须要在做完基础作业X之后的 下Z分钟, (如果难理解,看样例)才能开始做另外一项作业Y,按照老师的说法:间隔的时间是为了让你反思的。
但神犇具有同时完成多项作业的能力,并且神犇切任何的题目只需要一分钟!!
现在神犇想知道,他需要多少时间来完成作业,数据保证神犇可以完成作业。
这道题是经典的拓补排序题
题解见课本
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <ctime> #include <iomanip> #include <algorithm> #include <cstdlib> #include <string> using namespace std; #define M 100000 struct T { int v,t; }q[M]; int head=1,tail=0,id[M],ans=0,now[M]; int map[1000][1000],m,n; void init() { memset(map,0,sizeof(map)); memset(id,0,sizeof(id)); cin>>n>>m; for(int i=1;i<=m;i++) { int x,y,v; cin>>x>>y>>v; map[x][y]=v; id[y]++; } } void work() { for(int i=0;i<n;i++) if(id[i]==0) { q[++tail].v=i; q[tail].t=1; } for(head=1;head<=tail;head++) { for(int i=0;i<n;i++) if(map[q[head].v][i]) { id[i]--; now[i]=max(now[i],q[head].t+map[q[head].v][i]); if(id[i]==0) { q[++tail].v=i; q[tail].t=now[i]; } } } } int main() { //freopen("1828.in","r",stdin); //freopen("1828.out","w",stdout); init(); work(); for(int i=1;i<=tail;i++) { //cout<<i<<' '<<q[i].v<<' '<<q[i].t<<endl; ans=max(ans,q[i].t); } cout<<ans<<endl; return 0; }
完事