【codeforces 514D】R2D2 and Droid Army

【题目链接】:http://codeforces.com/contest/514/problem/D

【题意】

给你每个机器人的m种属性p1..pm
然后r2d2每次可以选择m种属性中的一种,进行一次攻击;
攻击过后每个机器人的该种属性都减少1;
可以最多攻击k次;
机器人只有m种属性都变为0之后才死掉;
然后问你如何分配这k次攻击,每次攻击时选择的属性;
使得连续的死掉的机器人的区间长度最长;

【题解】

对于选择的一个区间[l..r]
如果要使得这个区间的机器人全都死掉;
则需要攻击的次数就为
max(a[l..r][1])+max(a[l..r][2])+...+max(a[l..r][m])
因为某一种属性的在这个区间的最大值如果都变成0了,那么其他的也就变成0了;
则问题就是RMQ问题了;
然后写个二分;
枚举左端点,二分右端点;
上面那个值小于等于k就符合,增大右端点
否则减小右端点
写了个ST算法的。没写线段树

【Number Of WA

0

【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define ps push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%lld",&x)
#define ref(x) scanf("%lf",&x)
#define ms(x,y) memset(x,y,sizeof x)

typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 1e5+100;
const int M = 5+3;
const int maxpow = 20;

int n,m,k;
int a[M][N],two[maxpow];
int f[M][N][maxpow],need[N];
int ans[M],len,temp[M];

int main()
{
    //freopen("F:\rush.txt","r",stdin);
    rei(n),rei(m),rei(k);
    rep1(i,1,n)
        rep1(j,1,m)
            rei(a[j][i]);
    two[0] = 1;
    rep1(i,1,17)
        two[i] = two[i-1]*2;
    need[1] = 0;
    int now = 1;
    rep1(i,2,100000)
        if (i==two[now])
        {
            now++;
            need[i]=need[i-1]+1;
        }
        else
            need[i]=need[i-1];
    rep1(i,1,m)
        rep1(j,1,n)
            f[i][j][0] = a[i][j];
    rep1(k,1,m)
    {
        for (int l = 1;two[l]<=n;l++)
        {
            rep1(i,1,n)
            {
                if (i+two[l]-1>n) break;
                int j = i+two[l]-1;
                f[k][i][l] = max(f[k][i][l-1],f[k][j-two[l-1]+1][l-1]);
            }
        }
    }
    rep1(i,1,n)
    {
        int l = i,r = n;
        while (l <= r)
        {
            int mid = (l+r)>>1;
            //i..mid
            int cd = need[mid-i+1],cost = 0;
            rep1(j,1,m)
            {
                temp[j] = max(f[j][i][cd],f[j][mid-two[cd]+1][cd]);
                cost+=temp[j];
            }
            if (cost<=k)
            {
                if (mid-i+1>len)
                {
                    rep1(j,1,m)
                        ans[j] = temp[j];
                    len = mid-i+1;
                }
                l = mid+1;
            }
            else
                r = mid-1;
        }
    }
    rep1(i,1,m)
        printf("%d ",ans[i]);
    //printf("
%.2lf sec 
", (double)clock() / CLOCKS_PER_SEC);
    return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7626449.html