题意:
有K个城市,第i城市至多有N[i]个人,每个城市有一个属性Q[i]。
对于N=∑N[i]个人,每个人有一个属性P[i]和价值W[i],把第i个人放进第j个城市中,当且仅当P[i]>Q[j]时,可以获得W[i]的价值,否则不获得价值。
求出满足价值和最大的人数分配方案。0<=N<=16000。
分析:
这道题不会dp,我等蒟蒻只能考虑贪心了。
先将每个人按W[i]值排序,从大到小处理。
对于当前的第i个人,放到当前①“还可容纳人的”②“Q[j]<P[i]的”③“最大的Q[j]所在的城市”。
条件①②判断是否可放,条件③使局部最优进而全局最优。
最后一些没放进任何城市的人随意插空放入即可。
有K个城市,第i城市至多有N[i]个人,每个城市有一个属性Q[i]。
对于N=∑N[i]个人,每个人有一个属性P[i]和价值W[i],把第i个人放进第j个城市中,当且仅当P[i]>Q[j]时,可以获得W[i]的价值,否则不获得价值。
求出满足价值和最大的人数分配方案。0<=N<=16000。
分析:
这道题不会dp,我等蒟蒻只能考虑贪心了。
先将每个人按W[i]值排序,从大到小处理。
对于当前的第i个人,放到当前①“还可容纳人的”②“Q[j]<P[i]的”③“最大的Q[j]所在的城市”。
条件①②判断是否可放,条件③使局部最优进而全局最优。
最后一些没放进任何城市的人随意插空放入即可。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXK = 109, MAXN = 16009;
int K, N[MAXK], Q[MAXK], P[MAXN];
struct weight
{
int node, w;
}W[MAXN];
int Sum;
int ans[MAXN];
bool cmp(const weight &A, const weight &B)
{
return A.w > B.w;
}
int main()
{
cin >> K;
for(int i = 1; i <= K; ++i)
{
cin >> N[i];
Sum += N[i];
}
for(int i = 1; i <= K; ++i) cin >> Q[i];
for(int i = 1; i <= Sum; ++i) cin >> P[i];
for(int i = 1; i <= Sum; ++i)
{
cin >> W[i].w;
W[i].node = i;
}
sort(W+1, W+Sum+1, cmp);
for(int i = 1; i <= Sum; ++i)
{
int maxQ = -1, flag = -1;
for(int j = 1; j <= K; ++j)
if(Q[j] < P[W[i].node] && maxQ < Q[j] && N[j])
{
maxQ = Q[j];
flag = j;
}
ans[W[i].node] = flag;
if(flag != -1) N[flag]--;
}
for(int i = 1; i <= Sum; ++i)
if(ans[W[i].node] == -1)
for(int j = 1; j <= K; ++j)
if(N[j])
{
ans[W[i].node] = j;
N[j]--;
break;
}
for(int i = 1; i <= Sum; ++i)
cout << ans[i] << ' ';
return 0;
}