• BZOJ4509 Angry Cows(dp)


    题意:

    大概就是一条线上有n个炸弹,然后让你随意扔一个爆炸半径为r的炸弹使他们全部爆炸,

    第一次被引爆的炸弹爆炸半径为r-1,第二次为r-2。。。

    求r最小是多少

    思路:

    用两个数组处理得到从左往右和从右往左到当前炸弹时的爆炸半径最小是多少,然后枚举投弹位置就可以了

    /* ***********************************************
    Author        :devil
    ************************************************ */
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <cmath>
    #include <stdlib.h>
    using namespace std;
    typedef long long LL;
    const int inf=0x3f3f3f3f;
    const int mod=1e9+7;
    const int N=5e4+10;
    int ml[N],mr[N],a[N],n;
    int main()
    {
        //freopen("in.txt","r",stdin);
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        memset(ml,inf,sizeof(ml));
        memset(mr,inf,sizeof(mr));
        ml[1]=mr[n]=0;
        int k=1;
        for(int i=2;i<=n;i++)
        {
            while(k+1<i&&a[i]-a[k+1]>ml[k+1]+1) k++;
            ml[i]=min(a[i]-a[k],ml[k+1]+1);
        }
        k=n;
        for(int i=n-1;i>=1;i--)
        {
            while(k-1>i&&a[k-1]-a[i]>mr[k-1]+1) k--;
            mr[i]=min(a[k]-a[i],mr[k-1]+1);
        }
        double ans=inf;
        for(int i=1,j=n;i<j;)
        {
            ans=min(ans,(double)max((a[j]-a[i])/2.0,(double)max(ml[i],mr[j])+1));
            if(ml[i+1]<mr[j-1]) i++;
            else j--;
        }
        printf("%.1f
    ",ans);
        return 0;
    }
  • 相关阅读:
    今天地震了(有震感)...
    上班了!
    C++ 中explicit的作用
    DoModal 函数的用法
    [导入]C++ GUi 选择
    [导入]C++资源之不完全导引(完整版)[转]
    [导入]The GUI Toolkit, Framework Page
    [导入]C/C++中调用SQLITE3的基本步骤
    ACM
    牛客NOIP暑期七天营提高组5+普及组5
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/5744110.html
Copyright © 2020-2023  润新知