hdu 1074 Doing Homework (状态压缩 dp)

题意:老师给你布置一堆作业每个作业都规定了 上交的时间  你做每个作业所花费的时间也给出   如果到规定时间没上交做也晚交一天就要被老师扣一分  让你给出一个合理的做作业顺序 按这个顺序做完作业时被老师扣的分最少 如果答案有多个按字典序输出

题目链接:点击打开链接

//状态压缩dp

#include<stdio.h>
#include<string.h>

#define inf 0x3fffffff

struct node
{
    char name[30];
    int die;//老师规定的时间
    int need;//需要的时间
}st[30];//存课程

struct stsort
{
    int need;//完成当前状态包含的课程
    int t;//当前状态已经被扣的分数
    int qian;//用于记录当前状态最后完成的课程的编号
}dp[1<<16];

int limit;

void print(int x)//输出完成各个课程的顺序
{
    int ans[30];
    int l;
    l=0;
    while(x>0)
    {
        ans[l++]=dp[x].qian;
        x=x-(1<<dp[x].qian);
    }
    l--;
    while(l>=0)
    {
        printf("%s\n",st[ans[l]].name);
        l--;
    }
    return ;
}
int getadd(int pos,int j)
{
    int i,top,low,sum=0;
    low=dp[pos-(1<<j)].need;
    top=low+st[j].need;
    pos=pos-(1<<j);
    for(i=0;(1<<i)<limit;i++)
    {
        if(((1<<i)&pos)==0)
        {
            if(st[i].die<top)
                sum+=st[i].die<low?(top-low):(top-st[i].die);
        }
    }
    return dp[pos].t+sum;
}
int main()
{
    int t,n,i,j;
    scanf("%d",&t);
    while(t--)
    {


        scanf("%d",&n);

        limit=1<<n;
        for(i=0;i<limit;i++)
            dp[i].t=inf;
        dp[0].t=dp[0].need=0;
        for(i=0;i<n;i++)
        {
            scanf("%s %d %d",st[i].name,&st[i].die,&st[i].need);
        }
        for(i=0;i<limit;i++)//遍历所有状态
        {
            for(j=0;(1<<j)<=i;j++)//遍历当前状态i  包含的科目
            {
                if(((1<<j)&i)!=0)//如果科目j包含在状态i中(j为i的子集)
                {
                        if(dp[i].t>getadd(i,j))//最后加入课程j被扣的分 比当前状态i的扣分少 更新状态i 记录最后加入的是j
                        {
                        dp[i].t=getadd(i,j);
                        dp[i].need=dp[i-(1<<j)].need+st[j].need;
                        dp[i].qian=j;
                        }
                        else if(dp[i].t==getadd(i,j)&&strcmp(st[j].name,st[dp[i].qian].name)>0)//保证字典序 相同状态被扣分也相同时 字典序大的应该最后加入这个状态
                        {
                           dp[i].qian=j;
                        }
                }
            }
        }
        printf("%d\n",dp[limit-1].t);
        print(limit-1);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值