ldu-自测二E、F

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变成未知。

猜你喜欢

转载自blog.csdn.net/weixin_45606191/article/details/109017728
今日推荐