zoukankan      html  css  js  c++  java
  • codeforces gym 100947 J. Killing everything dp+二分

    J. Killing everything
    time limit per test
    4 seconds
    memory limit per test
    64 megabytes
    input
    standard input
    output
    standard output

    There are many enemies in the world such as red coders and hackers. You are trying eliminate everybody. Everybody is standing on a road, which is separated into 109 sections. The sections are numbered 1, 2, 3, 4, …109 from west to east. You want to kill N enemies. The ith enemy will be standing on the section Ai. In order to kill the enemies, you prepared P small bombs and Q large bombs. You can choose a positive integer w as a parameter for energy consumption. Then, a small bomb can kill all enemies in at most w consecutive sections, and a large bomb can kill all enemies of at most 2w consecutive sections.

    Enemies can be killed by more than one bomb. You want to kill all enemies. Since it is expected that many civilians will walk down that road, for the sake of safety, you have to fix the positions of the bombs and minimize the value of w.

    So you decided to Write a program that, given information of the enemies and the number of bombs, determine the minimum value of w so all enemies can be killed.

    Input

    The input consists of several test cases, the first line contains the number of test cases T. For each test case: The first line of input contains three space separated integers N, P, Q (1 ≤ N ≤ 2000, 0 ≤ P ≤ 105, 0 ≤ Q ≤ 105), where N is the number of the enemies, P is the number of small bombs, and Q is the number of large bombs.

    The ith line (1 ≤ i ≤ N) of the following N lines contains an integer Ai, the section where the ith enemy will be standing.

    Output

    Output: For each test cases print the solution of the problem on a new line.

    Examples
    input
    1
    3 1 1
    2
    11
    17
    output
    4
    Note

    In the sample test case you have 3 enemies at positions: 2, 11, 17.

    For w = 4, one possible solution is to throw one small bomb on segment 1 - 4, and one large bomb on segment 11 - 18. This configuration will kill all three enemies.

    There is no configuration with w < 4 that can kill them all.

    题意:给你n个位置,p个小炸弹,q个大炸弹;小炸弹可以连续炸w长度,大炸弹可以连续炸2*w长度

    思路:显然二分答案求最小的w,问题在于如何check;

       dp[i][j]表示炸完i之前所有点,使用j个小炸弹,最少需要多少个大炸弹;

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<set>
    #include<map>
    #include<bitset>
    #include<time.h>
    using namespace std;
    #define LL long long
    #define pi (4*atan(1.0))
    #define eps 1e-4
    #define bug(x)  cout<<"bug"<<x<<endl;
    const int N=2e3+10,M=5e5+10,inf=1e9+7,mod=1e9+7;
    const LL INF=1e18+10,MOD=1e9+7;
    
    int n,p,q;
    int nex[N][2];
    int dp[N][N],a[N];
    int check(int x)
    {
        for(int i=1;i<=n;i++)
        {
            nex[i][0]=lower_bound(a+1,a+n+2,a[i]+x)-a;
            if(2*x-inf+a[i]>0)nex[i][1]=n+1;
            else nex[i][1]=lower_bound(a+1,a+n+2,a[i]+x+x)-a;
        }
        for(int i=0;i<=n+1;i++)
        {
            for(int j=0;j<=p;j++)
                dp[i][j]=inf;
        }
        dp[1][0]=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<=p;j++)
            {
                int v=nex[i][0];
                dp[v][j+1]=min(dp[v][j+1],dp[i][j]);
                v=nex[i][1];
                dp[v][j]=min(dp[v][j],dp[i][j]+1);
            }
        }
        for(int i=0;i<=p;i++)
            if(dp[n+1][i]<=q)return 1;
        return 0;
    }
    int main()
    {
        int T,cas=1;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d",&n,&p,&q);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            if(p+q>=n)
            {
                printf("1
    ");
                continue;
            }
            sort(a+1,a+1+n);
            a[n+1]=inf*2;
            int s=1;
            int e=inf,ans=-1;
            while(s<=e)
            {
                int mid=(s+e)>>1;
                //cout<<mid<<endl;
                if(check(mid))
                    e=mid-1,ans=mid;
                else s=mid+1;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    window.onload和$(document).ready(function(){})的区别
    javascript:让表单 文本框 只读,不可编辑的方法
    JQuery操作下拉框
    项目中常用js方法整理common.js
    embed标签动态改变Src的值,局部刷新播放其他视频的javascript方法
    在BootStrap的modal中使用Select2
    小数点校验,只允许输入数字,小时点后只有两位
    带左右按钮的左右循环滚动轮播图,图片上带css3动效,用于显示文字
    JavaScript 函数方法
    JavaScript 函数方法
  • 原文地址:https://www.cnblogs.com/jhz033/p/7222433.html
Copyright © 2011-2022 走看看