<span>codeforces730I Olympiad in Programming and Sports(姿势题 优先队列?dp?)</span>

题意:

给你s(3000)个人,有两个社团,分别招收n和m(n+m<=s)个人,

每个人对这两个社团分别有一个自己的喜爱值(3000),

问怎样安排使得总的喜爱值最大,spj

思路:

如果n+m==s的话,裸的n^2的dp记一下前驱。。然而可以小于的话,

我除了n^3的就没有其他思路了。。。(弱就是弱)

看了看别人的代码,大概懂了,就是先把对第一个社团最喜爱的n个人放入,

然后对于第二个社团,每放一个人,就比较一下:

还没有加入社团的人(1)对第一个社团贡献最大的人的贡献+在第一个社团中的人(2)如果转到第二个社团所得到的最大贡献

和还没有加入这团的人(3)对第二个社团贡献最大的人的贡献做比较

如果前者大,就把(2)从第一个社团调到第二个社团,然后把(1)加入第一个社团

反之则把(3)加入第二个社团。

这样重复m次,就完成了

对于维护这三类,用三个优先队列吧。

/* ***********************************************
Author        :devil
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <string>
#include <time.h>
#include <cmath>
#include <stdlib.h>
#define LL long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ou(a) printf("%d\n",a)
#define pb push_back
#define pii pair<int,int>
#define mkp make_pair
#define IN freopen("in.txt","r",stdin);
#define OUT freopen("out.txt","w",stdout);
using namespace std;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int N=3e3+10;
int s,n,m,a[N],b[N],c[N],ans;
priority_queue<pii>p1,p2,tmp;
int main()
{
    scanf("%d%d%d",&s,&n,&m);
    for(int i=1;i<=s;i++) scanf("%d",&a[i]),p1.push(mkp(a[i],i));
    for(int i=1;i<=s;i++) scanf("%d",&b[i]),p2.push(mkp(b[i],i));
    while(n--)
    {
        int u=p1.top().second;
        p1.pop();
        c[u]=1;
        ans+=a[u];
        tmp.push(mkp(b[u]-a[u],u));
    }
    while(m--)
    {
        while(!p1.empty()&&c[p1.top().second]) p1.pop();
        while(!p2.empty()&&c[p2.top().second]) p2.pop();
        if(p1.top().first+tmp.top().first>p2.top().first)
        {
            int u=p1.top().second,v=tmp.top().second;
            p1.pop();tmp.pop();
            c[u]=1;c[v]=2;
            tmp.push(mkp(b[u]-a[u],u));
            ans+=b[v]-a[v]+a[u];
        }
        else
        {
            int u=p2.top().second;
            p2.pop();
            c[u]=2;
            ans+=b[u];
        }
    }
    printf("%d\n",ans);
    for(int i=1;i<=s;i++) if(c[i]==1) printf("%d ",i);
    printf("\n");
    for(int i=1;i<=s;i++) if(c[i]==2) printf("%d ",i);
    return 0;
}

 

全部评论

相关推荐

05-12 10:10
已编辑
门头沟学院 人工智能
写这篇之前我犹豫了挺久。一方面是怕被人骂,&quot;又一个收割焦虑的转行帖&quot;;另一方面是看了太多用&nbsp;GPT&nbsp;套娃出来的「学习路线」文章,AI&nbsp;味重得让人没法读完。所以这篇全是亲身踩过的坑,时间线、用过的项目、当时的心路全都尽量原样写出来。如果你是大学生在迷茫要不要转&nbsp;AI,或者已经在转的路上,希望能给点参考。&nbsp;一个反共识的开场:你以为进&nbsp;OpenAI&nbsp;的人都是博士?&nbsp;先讲个故事,跟我没关系,但跟所有想转&nbsp;AI&nbsp;的人都有关系。&nbsp;OpenAI&nbsp;的&nbsp;Sora&nbsp;团队(就是搞文生视频那个)一共&nbsp;13&nbsp;个人。这里面有两个人特别有意思:&nbsp;Will&nbsp;DePue,密歇根大学计算机系,直接辍学了。17...
_hengheng:我也本,也算是做ai相关,我最开始感觉做ai工程师有多么多么困难,后来发现懂了原理后整体训练完全可以看成一个流程化的内容,开源方案太多了,大多基本都是按着模子在自家业务上做各种操作,就算是大厂的小部门也没那么多资源去训基模,反而更多的是像怎么把技术往业务方向靠近了,不过当前时代如果本科学历没那么好加上自己执行力不是特别强还真不建议走ai工程师这条路,可以试试其他ai的偏业务方向,不然校招不太好杀出来
点赞 评论 收藏
分享
站队站对牛:进度也算很慢的了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务