Doing Homework HDU - 1074

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Doing Homework HDU - 1074相关的知识,希望对你有一定的参考价值。

Doing Homework HDU - 1074

题意:

有n个任务,每个任务有一个截止时间,超过截止时间一天,要扣一个分。
求如何安排任务,使得扣的分数最少。
(1<=n<=15)

题解:

n很小,可以往状压dp方向去想
我们用i枚举所有的状态,然后对于第j个任务,tmp=i-(1<<j),tmp表示状态i在未完成j的前一个状态
tim[]表示当前状态所花费的时间,那么完成第j个任务所扣分数为score=tim[tmp]+cost[j]-dead[j],完成tmp所需时间+完成任务j所需时间-截止日期,超出多少扣多少分数
dp[i]表示i状态下的的最小扣分,dp[i]=min(dp[tmp]+score)
为了方便答案的输出,我们用pre[i]记录,最后一个完成状态i所办的任务,pre[i]=j,这样记录是为了之后方便输出,w=i-(1<<pre[i])就是在任务j之前的状态,然后依次寻找w-(1<<pre[w])
在循环任务j时,要从后向前找,因为题目所给的数据是字典序递增的,而我们最后的输出是根据pre倒着输出的,所以逆着寻找可以保证输出的字典序最小

代码:

我的代码不知道哪里错了,一直wa,先贴上网上的正代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<ctime>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 15
#define MOD 10007
#define E 1e-6
#define LL long long
using namespace std;
char str[20][101];
int dp[1<<N],pre[1<<N],times[1<<N];
int dead[N],cost[N];
void print(int x){//递归输出作业顺序
    if(!x)
        return;
    print(x-(1<<pre[x]));
    printf("%s\\n",str[pre[x]]);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%s%d%d",&str[i],&dead[i],&cost[i]);
        memset(times,0,sizeof(times));
        memset(pre,0,sizeof(pre));
 
        for(int i=1;i<(1<<n);i++){//枚举所有状态
            dp[i]=INF;//初始化状态i的扣分
            for(int j=n-1;j>=0;j--){//从后向前找
                int temp1=1<<j;
                if(!(i&temp1))//状态i不存在作业j完成的情况
                    continue;
 
                int temp2=i-temp1;//未完成作业j的状态
                int score=times[temp2]+cost[j]-dead[j];//计算扣分
 
                if(score<0)//最小扣分为0
                    score=0;
                if(dp[i]>dp[temp2]+score){
                    dp[i]=dp[temp2]+score;//记录最小扣分
                    times[i]=times[temp2]+cost[j];//到达状态i所花费的时间
                    pre[i]=j;//状态i的前驱
                }
            }
        }
        printf("%d\\n",dp[(1<<n)-1]);
        print((1<<n)-1);
    }
    return 0;;
}

以上是关于Doing Homework HDU - 1074的主要内容,如果未能解决你的问题,请参考以下文章

Doing Homework HDU - 1074

[2016-03-28][HDU][1074][Doing Homework]

HDU1074 Doing Homework —— DP

[HDU1074]Doing Homework (状压DP)

HDU 1074 Doing Homework

HDU 1074:Doing Homework(状压DP)