2017.1.19总结

这道题是最优骗分+贪心

原题:


 

有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;
}
复制代码

完事

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值