两种方法:
1:把分数从大到小排序然后去安排每天的任务,如果安排不了了就舍弃。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
int arr[1005];
struct P
{
int day;
int score;
} p[1005];
int cmp(const P &a,const P &b)
{
if(a.score>b.score) return 1;
if(a.score==b.score && a.day<b.day) return 1;
return 0;
}
int main()
{
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
memset(arr,0,sizeof(arr));
for(int i=0; i<n; i++)
{
cin >> p[i].day;
}
for(int i=0; i<n; i++)
{
cin >> p[i].score;
}
sort(p,p+n,cmp);
long long int sum=0;
int l=1;
for(int i=0; i<n; i++)
{
int j;
for(j=p[i].day;j>0;j--)
{
if(!arr[j])
{
arr[j]=1;
break;
}
}
if(j==0) sum+=p[i].score;
}
cout << sum << endl;
}
return 0;
}
值得注意的是安排时从限制天数开始查找,用一个数组记录哪几天安排过任务了,优先安排的因为排过序,所以是最优方案。
2:优先队列处理,这个方法感觉很灵巧,直接排序pair默认从小到大排序第一元素再排序第二元素。所以排完了是按照天数排序从小到大的。然后依次把分数放入从小到大的优先队列,如果当天安排过任务,就把最前面的最小的拿出来,算作舍弃的分数。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int MAX_N = 1 << 17;
const int INF = 0x3f3f3f3f;
P arr[MAX_N];
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; ++i)
scanf("%d", &arr[i].first);
for (int i = 0; i < n; ++i)
scanf("%d", &arr[i].second);
sort(arr, arr + n);
int ans = 0, day = 0;
priority_queue<int, vector<int>, greater<int> > pque;
for (int i = 0; i < n; ++i)
{
pque.push(arr[i].second);
if (day < arr[i].first)
{
++day;
continue;
}
ans += pque.top();
pque.pop();
}
printf("%d\n", ans);
}
return 0;
}