题目链接:HDOJ 1789
题意:和状压dp那个类似,不过这个和那个区别就是 这个每门作业都只要一天就可以完成,而且一旦没有在规定期限内完成就直接罚分,一次性罚完,所以这题可以直接排序后贪心做(做完每们作业所需时间(代价相同),贪心解这类题目较多)
代码:
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<iostream>
#include<stack>
#include<queue>
#include<limits>
using namespace std;
#define debug 0
#define Max(a,b) ((a>b)?a:b)
#define M(a) memset(a,0,sizeof(a))
#define REP(o) for(int i=1;i<=o;i++)
const int maxn = 1000 + 5;
struct R
{
int time;
int score;
}r[maxn];
int n, caseNum, total;
bool vis[10010];
bool cmp(const R a, const R b){//按分数递减,分数相同按时间递增排序
if (a.score == b.score)
return a.time<b.time;
return a.score>b.score;
}
void Do()
{
int sum = 0, j;
sort(r + 1, r + n + 1, cmp);
for (int i = 1; i <= n; i++)
{
for (j = r[i].time; j>0; j--)//望前查找 若有的时间还未被占 把这一天记为已访问
{
if (!vis[j])
{
vis[j] = 1;
break;
}
}
if (!j) //如果 j = 0把这个分数加到罚分里
{
sum += r[i].score;
}
}
printf("%d\n", sum);
}
int main()
{
#if debug
freopen("in.txt", "r", stdin);
#endif // debug
while (~scanf("%d", &caseNum))
{
while (caseNum--)
{
M(vis);
scanf("%d", &n);
REP(n)
{
scanf("%d", &r[i].time);
}
REP(n)
{
scanf("%d", &r[i].score);
}
Do();
}
}
return 0;
}