【线性DP】P10156 [LSOT-2] 胜者组

解题思路

开一个结构体存储学生的序号、a值和c值。对输入的数据,先按c值排序,c值相同情况下按序号排序。

定义dp数组,dpij表示排序后的前i个人里,选了j人的最小满意度。

初始化:

bash 复制代码
memset(dp,0x3f,sizeof(dp));
for (int i = 0; i <= n; i++) dp[i][0] = 0;
  • 如果j是奇数,一种情况是如果前一个人和他同一个团体,不选第i个人,可以使dpij=dpi-1j;还有一种考虑选第i个人,dpij=min(dpij,dpi-1j-1+si.a-xsi.idx)。(+si.a-xsi.idx,我们可以这样考虑:最终t出去的人是偶数,现在j是奇数,所以根据不满意的计算ai+aj+x*|i-j|,后面会有一个数和j配对,这里就把j对应的序号si.idx减去)。
  • 如果j是偶数,一种情况是选第i个,且上一个人和第i个人同组,就可以得出dpij=min(dpij,dpi-1j-1+si.a+x*si.idx)。还有一种情况是不选第i个人,则dpij=min(dpij,dpi-1j)。

AC Code

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,m,k,x,dp[5005][5005];
struct stu{
	int a,c,idx;
	friend bool operator<(stu p,stu q){
		if(p.c!=q.c) return p.c<q.c;
		return p.idx<q.idx;
	}
}s[5005];
int main(){
	cin>>n>>m>>k>>x;
	m=n-m;
	if(m%2) m++;
	for(int i=1;i<=n;i++){
		s[i].idx=i;
		cin>>s[i].a;
	}
	memset(dp,0x3f,sizeof(dp));
	for (int i = 0; i <= n; i++) dp[i][0] = 0;
	for(int i=1;i<=n;i++)
		cin>>s[i].c;
	sort(s+1,s+n+1);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=min(i*1ll,m);j++){
			if(j%2!=0){
				if(s[i].c==s[i-1].c) dp[i][j]=dp[i-1][j];
				dp[i][j]=min(dp[i][j],dp[i-1][j-1]+s[i].a-x*s[i].idx);
			}
			else{
				dp[i][j]=dp[i-1][j];
				if(s[i].c==s[i-1].c) dp[i][j]=min(dp[i][j],dp[i-1][j-1]+s[i].a+x*s[i].idx);
			}
		}
	}
	if(dp[n][m]<1e18) cout<<dp[n][m];
	else cout<<"Impossible";
	return 0;
}
相关推荐
无名猿1 小时前
map / set 完全指南:红黑树与有序容器
数据结构·c++·性能优化·stl·标准库
朝朝辞暮i1 小时前
C++ 第 28 课:Lambda 表达式
开发语言·c++·算法
All for pursuit.1 小时前
【回溯-3】39.组合总和
数据结构·c++·算法·leetcode
见叶之秋1 小时前
【C++】一条双向链的诞生:手写 list 模拟实现
c++
沫璃染墨1 小时前
《从零入门Linux系统篇(五十六):线程篇·九——生产者消费者模型:从条件变量到BlockingQueue实现》
linux·服务器·c++·驱动开发·设计模式·架构·系统架构
张小姐的猫1 小时前
【Linux】网络编程 —— 五种IO模型
linux·运维·服务器·网络·c++·人工智能·php
重生之小比特2 小时前
【C++进阶】02 Linux基本指令
java·数据库·c++
(Charon)2 小时前
【C++面试】手写智能指针(一):从unique_ptr理解独占所有权与移动语义
开发语言·c++
李游Leo2 小时前
HarmonyOS 7 + Spatial Recon Kit-C++:3DGS 输入帧内参与位姿的版本一致性门禁【鸿蒙心迹】
c++·3d·harmonyos