【悬赏关注】看不懂哪错了
查看原帖
【悬赏关注】看不懂哪错了
999274
CNS_5t0_0r2楼主2024/6/25 16:49
#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 1e5 + 9,M = 1e5 + 9,P = 109;

int n,m,p;
int d[N];
struct cat{
	int h,t;
	int a;//饲养员如果要接到这只猫就必须在a = t - (d[1] + d[2] + ... + d[h[i]])时刻从1号山出发 
} c[M];

bool cmp(cat x,cat y){
	return x.a < y.a;
}

int s_a[M];

int que[M];
int head,tail;

int dp[P][M];

int val(int i,int j,int k){//以k作为决策时dp[i][j]的值 
	return dp[i - 1][k] + c[j].a * (j - k) - (s_a[j] - s_a[k]);
}

double slope(int i,int p1,int p2){
	return (double)((dp[i - 1][p1] + s_a[p1]) - (dp[i - 1][p2] + s_a[p2])) / (double)(p1 - p2);
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	cin >> n >> m >> p;
	
	for(int i = 2;i <= n;i++){
		cin >> d[i];
		d[i] += d[i - 1];
	}
	
	for(int i = 1;i <= m;i++){
		cin >> c[i].h >> c[i].t;
		c[i].a = c[i].t - d[c[i].h];
	}
	
	sort(c + 1,c + m + 1,cmp);
	for(int i = 1;i <= m;i++)
		s_a[i] = s_a[i - 1] + c[i].a;

	memset(dp,0x3f,sizeof dp);
	dp[0][0] = 0;
	
	for(int i = 1;i <= p;i++){
		head = 1;tail = 0;
		que[++tail] = 0;
		for(int j = 1;j <= m;j++){
			while(head < tail && /*slope(i,que[head],que[head + 1]) <= c[j].a*/
			
				((dp[i - 1][que[head + 1]] + s_a[que[head + 1]]) - (dp[i - 1][que[head]] + s_a[que[head]])) < c[j].a * (que[head + 1] - que[head])) 
				head++;
			int k = que[head];//队头为最优决策点 
			dp[i][j] = val(i,j,k);
			while(head < tail && /*slope(i,que[tail],que[tail - 1]) >= slope(i,j,que[tail])*/
				((dp[i - 1][que[tail]] + s_a[que[tail]]) - (dp[i - 1][que[tail - 1]] + s_a[que[tail - 1]])) * (que[j] - que[tail]) > ((dp[i - 1][j] + s_a[j]) - (dp[i - 1][que[tail]] + s_a[que[tail]])) * (que[tail] - que[tail - 1]))
				tail--;
			que[++tail] = j;
		}
	}
	
	cout << dp[p][m];
	return 0;
}
2024/6/25 16:49
加载中...