E. CoolGuang’s Division(Easy Version)
Description
纳新开始了
一大批的学妹学弟们将来到实验室
接下来就面临一个非常棘手的问题,位置怎么分配呢
现在来抽象化这个问题:
有N个学生,其中每个学生都有一个位置ai
起初每个位置可以有多个人,但是最终每个位置只能有一个人
所以CoolGuang的决策有很重要的作用,CoolGuang每次只可以使得一个人向前移动一位
但是呢,学弟学妹们是有 讨厌度的,每次让第i个向前移动一次就要花费bi
问CoolGuang怎样分配,才可以使得学弟学妹们对它的总讨厌度最小并输出最小的总讨厌度
Input
第一行一个N,代表有n个学生(1<=N<=300000)
接下来N行,每行两个数字ai,bi代表第i个学生的位置与移动一次的讨厌度
1<=ai<=1e9,bi=1
Output
最小讨厌度
input
3
1 1
1 1
3 1
output
1
一开始我理解错2遍题意。一:他只能往前走,即+1,不能-1。二、座位号不一定是连续的,你可以看成有1e9个座位,只要最后没有一座位两人的情况。
因为[i]固定是一,只要考虑步数即可。
普通暴力一定超时。要用一个变量 t 储存,表示前t个座位可以不用考虑(一是因为只能往前走,二是之前遍历后,t到a[i]之间都有值了)
#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll mod=1e9+7;
const int maxn=3e5+7;
int n,m,a[maxn],x,y,cnt,t;
ll sum;
map<int,int>mp;
ll qpow(ll a, int b){
ll ans=1;
while(b){
if(b&1) ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&x);
mp[x]++; a[i]=x;
scanf("%d",&x);
}
sort(a,a+n);
for(int i=1;i<=n;i++){
y=a[i]; t=max(t,y+1);
while(mp[y]>1){
while(mp[t]) t++;
mp[t]=1;
sum+=t-y;
mp[a[i]]--;
}
}
printf("%lld",sum);
}
F. CoolGuang’s Division(Hard Version)
只用一个改动,b[i]从固定的1变成未知。