Codeforces Round #336 (Div. 2) 608C Chain Reactio DP

这题应该如何正确思考?

先给了n个灯塔的位置和它们各自的摧毁范围,要求最后立的这个灯塔,它的作用实际上可以是:

保证你可以在[0,n]之间的任意位置 i 开始 激活灯塔,也就是说把[ i+1,n]这个范围的灯塔全部摧毁。

这样的话,可以设一个数组dp[maxn],计算在[0,maxn]之间 每一个 i(灯塔) 被激活时,在 [0,i] 范围内 存活的灯塔数量。

(即dp[i] 表示,第i个灯塔被激活时,[0,i]存活的灯塔数量。)

设一个max,为最大存活的灯塔数量,n-max 即为答案。


另,做这题得到一个好消息和一个坏消息。

好消息是,可以用

 ios::sync_with_stdio(0);
    cin.tie(NULL);

两个语句来加快 cin cout 的输入输出速度,这两句话的意思是,解除cin,cout与 stdio 的关系,不再兼容C 的输入输出。据说用了之后速度与scanf相差无几。

坏消息是:

经过亲测:本题 用了这两句+cin、cout是155ms,用printf、scanf是62ms............

代码:


#include <stdio.h>
using namespace std;
int b[1000005],dp[1000005]; //全局变量初始化为0,省去memset
int main()
{
    int n,a;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a);
        scanf("%d",&b[a]);
    }
    if(b[0]>0) //用 > 不用 != 因为 > 的判断貌似比!=要快
        dp[0]=1;
    int ans=0;
    for(int i=1;i<1e6+5;i++)
    {
        if(b[i]==0)
            dp[i]=dp[i-1];
        else
        {
            if(b[i]>=i)  //如果b[i]>i,则灯塔的范围肯定能全部覆盖[0,i-1],
                dp[i]=1;   //最后只剩下它自己
            else
                dp[i]=dp[i-b[i]-1]+1; //如果不是,摧毁掉其所能覆盖的范围后,+1(它本身)
        }
        if(dp[i]>ans)
            ans=dp[i];
    }
    printf("%d\n",n-ans);
    return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值