【HDU 1789】 Doing Homework again 贪心 优先队列

Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Every teacher gives him a deadline of handing in the homework. If Ignatius hands in the homework after the deadline, the teacher will reduce his score of the final test. And now we assume that doing everyone homework always takes one day. So Ignatius wants you to help him to arrange the order of doing homework to minimize the reduced score.
Input
The input contains several test cases. The first line of the input is a single integer T that is the number of test cases. T test cases follow.
Each test case start with a positive integer N(1<=N<=1000) which indicate the number of homework… Then 2 lines follow. The first line contains N integers that indicate the deadlines of the subjects, and the next line contains N integers that indicate the reduced scores.
Output
For each test case, you should output the smallest total reduced score, one line per test case.
Sample Input
3
3
3 3 3
10 5 1
3
1 3 1
6 2 3
7
1 4 6 4 2 4 3
3 2 1 7 6 5 4
Sample Output
0
3
5

题意:n个作业,每个作业有截止日期和权值。每天只能写一个,问最小的权值损失。

思路:

虽然这题DP和O(n2)的贪心都能过,但还是想写优化的算法。
1.对作业进行截止日期从小到大排序。优先完成截止日期近的。
2.每天可以做一个作业,每做一个作业占用的天数就++。先贪心遇到一个作业就计入权值。
3.若当前作业的截止日期已经小于我们当前排到它的时间的话。就去掉一个权值最小的,跟它换。这一步利用优先队列。(因为前面已经贪心遇到一个作业就进队列,如果它就是最小的也会被T出来。)。
整体代码时间复杂度O(n n \sqrt{n} n )。

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include 
#include
#include 
#include 
#include 
#include
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 1e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){
     return x&(-x);}
ll gcd(ll a,ll b){
     return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){
     if(!b){
     d=a,x=1,y=0;}else{
     ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){
     ll res=1;a%=MOD;while(b>0){
     if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){
     return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){
     ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){
      ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {
     if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
int dir[4][2] = {
      {
     1,0}, {
     -1,0},{
     0,1},{
     0,-1} };

typedef struct Information
{
     
    ll t;
    ll val;
}I;
I a[maxn];

bool cmp(I a, I b)
{
     
    return a.t < b.t;
}

int main()
{
     
    int kase;
    cin>>kase;
    while(kase--)
    {
     
        ll n = read();
        priority_queue<ll, vector<ll>,greater<ll> > q;
        ll sum = 0;
        rep(i,1,n) a[i].t = read();
        rep(i,1,n) a[i].val = read(), sum += a[i].val;
        sort(a+1,a+1+n,cmp);
        ll ans = 0, day = 1;
        rep(i,1,n)
        {
     
            ans += a[i].val;
            q.push(a[i].val);
            if(day<=a[i].t) day++;
            else
            {
     
                ans -= q.top();
                q.pop();
            }
        }
        cout<< sum - ans <<'\n';
    }
    return 0;
}

你可能感兴趣的:(HDU,贪心,队列,HDU,题解,贪心,优先队列)