Description
Input
第一行两个整数 N (2 <= N <= 200)和 K(1 <= K <= N/2),分别表示参赛人数和每轮预赛的晋级人数。
接下来 N 行, 第 i 行为第 i 个选手的情况, 每行三个整数, 分别为该选手参加第一轮预赛的得分 Xi,参加第二轮预赛的得分 Yi,以及该选手的所属国度 Zi( 1 表示阿斯嘉德, 0表示米德加尔特)。
注意: Xi 之间的值互不相同, Yi 之间的值互不相同。
Output
输出一行一个整数,为阿斯嘉德最高的得分总和。
Sample Input
5 2
90 60 0
40 50 1
3 1 1
4 4 0
1 2 1
Sample Output
54
Data Constraint
对于 30%数据, N≤20;
对于 100%数据, N≤200, Xi, Yi 的总和小于 2^31。
Solution
题目大意就是给你n个人的国籍(0/1)和两轮比赛的分数,他们必须参加两轮中的一轮比赛,将每轮比赛分数排名的前k个的加入到国家的总分,最大化1国的分数。
注意到N非常小,于是我们可以枚举一个分界线,表示第一轮比赛中排名第K的人的分数,设为Kx,那么大于等于Kx的加入总分
那么我们可以发现,对于所有0国的人i,若Xi<Kx,则显然把他丢进第一轮里。
还可以发现对于所有1国的人i,若Xi<Kx,则显然把他放进第二轮
那么我们将除去0国Xi<Kx的人抽出来组成一个新的集合,再来做dp。
按第二轮分数从大到小排序 我们可以设f[i][j]表示在前i个选手中,有j个选手参加了第一轮预选赛并且晋级时1王国的选手最高的得分总和。因为所有被选出来dp的人要么进入第一轮的前K位,要么进入了第二轮,又因为第二轮分数有序,所以i-j即为第二轮的前列,后面的人的排名不可能超过他们。
至此,有三种情况:
① 0队选手且分数≥x
1、放第一场 F[i-1][j-1] (j>0)
2、放第二场 F[i-1][j]
② 1队选手且分数< x
1、放第二场 F[i-1][j]+Sec[i] (i>j & i-j<=k) //第二轮晋级人数不能超过k,超过则不计分
F[i-1][j] (else)
③ 1队选手且分数≥x
1、放第一场 F[i-1][j-1]+Fir[i] (j>0)
2、放第二场 F[i-1][j]+Sec[i] (i>j & i-j<=k)
F[i-1][j] (else)
最后答案即为max{f[当前选出集合元素个数][0~k]}
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mem(x,y) memset(x,y,sizeof(x))
#define I int
#define F(i,a,b) for(I i=a;i<=b;i++)
#define N 202
using namespace std;
I rd(){
I x=0;char ch=getchar();
while(ch<'0'||ch>'9'){ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x;
}
I n,k,tot,ans,f[N][N];
struct al{I x,y,z;}a[N];
struct ct{I x,y,z;}c[N];
I cmp(ct s,ct t){return s.y>t.y;}
int main(){
n=rd();k=rd();
F(i,1,n){
a[i]=al{rd(),rd(),rd()};
}
F(l,1,n){
tot=0;
mem(f,0);
F(i,1,n){
if(a[i].x>=a[l].x){
++tot;
c[tot]=ct{a[i].x,a[i].y,a[i].z};
}
else{
if(a[i].z==1){
++tot;
c[tot]=ct{a[i].x,a[i].y,a[i].z};
}
}
}
sort(c+1,c+1+tot,cmp);
F(i,1,tot){
F(j,0,min(i,k)){
f[i][j]=max(f[i][j],f[i-1][j]);
if(!c[i].z){
if(j) f[i][j]=max(f[i][j],f[i-1][j-1]);
}
else{
if(c[i].x<a[l].x){
if(i>j&&i-j<=k) f[i][j]=max(f[i][j],f[i-1][j]+c[i].y);
}
else{
if(j) f[i][j]=max(f[i][j],f[i-1][j-1]+c[i].x);
if(i>j&&i-j<=k) f[i][j]=max(f[i][j],f[i-1][j]+c[i].y);
}
}
ans=max(ans,f[i][j]);
}
}
}
printf("%d\n",ans);
return 0;
}
作者:zsjzliziyang
QQ:1634151125
转载及修改请注明
本文地址:https://blog.csdn.net/zsjzliziyang/article/details/98475050