首页 > 代码库 > HDU 1074 状态压缩DP 第一次写 多多指教

HDU 1074 状态压缩DP 第一次写 多多指教

给你n个数表示有n门作业,下面n行  每行三个数 分别为学科名 截止时间  需要多久才能完成

如果逾期一天则扣掉一学分, 要你求出完成所有作业而被扣最小的学分, 并将完成作业的顺序输出.(时间相同时 按照单词字典数输出)

学分相同时按照字典数输出   目前对于从n-1到0不是很理解

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<math.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define N 1<<16
struct node
{
    int end,time;
    char str[123];
}a[N];
struct point
{
    int time,sum,e,f;
}dp[N];
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%s%d%d",a[i].str,&a[i].end,&a[i].time);
        int sum=1<<n;///要满足于11111(n个1)
        for(int s=1;s<sum;s++)
        {
            dp[s].sum=INF;///初始化
            for(int i=n-1;i>=0;i--)
            {
                int ans=1<<i;
                if(s&ans)///s恒大于等于ans
                {
                    int e=s-ans;
                    int timecha=dp[e].time+a[i].time-a[i].end;
                    if(timecha<0)///变换所需要的时间
                        timecha=0;
                    if(timecha+dp[e].sum<dp[s].sum)
                    {
                        dp[s].sum=timecha+dp[e].sum;///超过的时间
                        dp[s].e=i;
                        dp[s].f=e;
                        dp[s].time=dp[e].time+a[i].time;///当前时间
                    }
                }
            }
        }
        printf("%d\n",dp[sum-1].sum);
        sum--;
        int w[20],ans=0;
        while(ans<n)
        {
            w[ans++]=dp[sum].e;
            sum=dp[sum].f;
        }
        for(int i=n-1;i>=0;i--)
            printf("%s\n",a[w[i]].str);
    }
    return 0;
}

 

HDU 1074 状态压缩DP 第一次写 多多指教