題目鏈接:https://vjudge.net/problem/CodeForces-514D
題目大意:現在有一排機器人(n個),每個機器人有m個屬性,你可以選擇一種屬性進行攻擊,使所有機器人的這一屬性都減1,當一個機器人所有屬性都小於等於0時就視爲被消滅了,現在你有k次攻擊的機會,請問最多能夠消滅連續的多少個機器人。
思路:因爲是找的連續的最大長度,(連續的……),所以想要消滅某連續區間的機器人,每種屬性攻擊的次數都必須達到改區段的最大值。所以這裏用RMQ維護一下區間最大值,然後枚舉n個起點,二分找出k次攻擊最遠能夠消滅到哪個位置。
代碼:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define mid ((l + r)>>1)
#define chl root<<1
#define chr root<<1|1
using namespace std;
typedef unsigned long long ull;
typedef long long LL;
const int manx=1e5+10;
int dp_max[manx][30][6],ans[7],len=0,mmax,m;
//dp_max[i][j][k]表示區間i~i+2^j-1的機器人第k種屬性的最大值
void solve(int l,int r)
{
int pos=l-1,sum,s=l;
while(l<=r)
{
sum=0;
int k=log2(mid-s+1);
for(int i=1; i<=m; i++)
sum+=max(dp_max[s][k][i],dp_max[mid-(1<<k)+1][k][i]);//查詢
if(sum<=mmax)
{
pos=mid;
l=mid+1;
}
else
r=mid-1;
}
if(pos!=s-1&&pos-s+1>len)
{
len=pos-s+1;
int k=log2(len);
for(int i=1; i<=m; i++)
ans[i]=max(dp_max[s][k][i],dp_max[pos-(1<<k)+1][k][i]);
}
}
int main()
{
int n,temp;
scanf("%d%d%d",&n,&m,&mmax);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
scanf("%d",&temp);
dp_max[i][0][j]=temp;
}
}
for(int j=1; j<=20; j++)
for(int i=1; i+(1<<j)-1<=n; i++)
for(int k=1; k<=m; k++)
dp_max[i][j][k]=max(dp_max[i][j-1][k],dp_max[i+(1<<(j-1))][j-1][k]);
for(int i=1; i<=n; i++)
solve(i,n);//枚舉起點
for(int i=1; i<m; i++)
printf("%d ",ans[i]);
printf("%d\n",ans[m]);
return 0;
}