codeforces730I Olympiad in Programming and Sports(姿式題 優先隊列?dp?)

題意:ios

給你s(3000)我的,有兩個社團,分別招收n和m(n+m<=s)我的,spa

每一個人對這兩個社團分別有一個本身的喜好值(3000),code

問怎樣安排使得總的喜好值最大,spjblog

思路:隊列

若是n+m==s的話,裸的n^2的dp記一下前驅。。然而能夠小於的話,string

我除了n^3的就沒有其餘思路了。。。(弱就是弱)it

看了看別人的代碼,大概懂了,就是先把對第一個社團最喜好的n我的放入,io

而後對於第二個社團,每放一我的,就比較一下:class

尚未加入社團的人(1)對第一個社團貢獻最大的人的貢獻+在第一個社團中的人(2)若是轉到第二個社團所獲得的最大貢獻stream

和尚未加入這團的人(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;
}
相關文章
相關標籤/搜索