hdu 1074 Doing Homework

来源:互联网 发布:怎么投诉阿里云 编辑:程序博客网 时间:2024/06/16 02:16

二进制状态压缩dp,第一次接触这个算法,同时吐槽一下自己:自己之前写博客从来不加注释,觉得自己会就OK了,博客是给自己看的,从没注意过看我博客的人的想法。 然而既然别人看你博客,那肯定是要学习你会然而别人不会的知识,如果不加注释的话,别人肯定看不懂,浪费别人的时间。自己写这道题深有体会, 看了好多大牛的博客,然而他们好多没加注释,搞得我根本就不知道他们写的是什么,自己想这道题想了好久,最后找到了一位写有注释的大牛的博客,终于看懂了。
这题起初我自己写想的是搜索,写完之后果断TLE,自己一算复杂度,15的阶乘1W亿,,Orz。
用二进制状态压缩,比如要求15门作业的最优解,那么肯定是从14门作业再添加一门,若完成14门作业的最优解已知的话,那么15门肯定是完成14门作业加上剩下的一门作业,因为剩下的一门有15种情况,(即第一门,第二门,…..第15门未完成),然后在这15种情况下再找到最优的一个,所以可以从前到后这样一步一步的求,分别求出第一门,第二门,,,,第n门的最优解,
题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=1074

Problem Description
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, 1 day for 1 point. And as you know, doing homework always takes a long time. 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 which is the number of test cases. T test cases follow.
Each test case start with a positive integer N(1<=N<=15) which indicate the number of homework. Then N lines follow. Each line contains a string S(the subject’s name, each string will at most has 100 characters) and two integers D(the deadline of the subject), C(how many days will it take Ignatius to finish this subject’s homework).

Note: All the subject names are given in the alphabet increasing order. So you may process the problem much easier.

Output
For each test case, you should output the smallest total reduced score, then give out the order of the subjects, one subject in a line. If there are more than one orders, you should output the alphabet smallest one.

Sample Input
2
3
Computer 3 3
English 20 1
Math 3 2
3
Computer 3 3
English 6 3
Math 6 3

Sample Output
2
Computer
Math
English
3
Computer
English
Math

Hint

In the second test case, both Computer->English->Math and Computer->Math->English leads to reduce 3 points, but the
word “English” appears earlier than the word “Math”, so we choose the first order. That is so-called alphabet order.
代码:

#include<stdio.h>#include<string.h>using namespace std;const int maxn=(1<<15)+10;//千万不能写成(1<<15+10),+的运算符优先于<<。const int inf=(1<<31)-1;//+oostruct{    int limit,actual;  //limit限制时间,actual实际所用时间    char name[110];} a[20];int dp[maxn],print[maxn],time[maxn]; //dp[]表示在这个状态对应被扣多少分,time[]表示在这个状态用了多少时间。这里所指的状态是指dp[i]中的i转化为二进制时对应的01串对应的状态,比如6为110,代表做了第二门和第三门作业,而第一门作业没做时的状态。void output(int x)  //倒过来打印路径{    if(!x) return;    output(x-(1<<print[x]));    printf("%s\n",a[print[x]].name);}int main(){    int nn,n;    scanf("%d",&nn);    while(nn--)    {        memset(time,0,sizeof(time));        int n,i,j;        scanf("%d",&n);        for(i=0; i<n; i++)            scanf("%s%d%d",a[i].name,&a[i].limit,&a[i].actual);        int total=1<<n;        for(i=1; i<total; i++)  //不要用十进制来看待i,应该用二进制来看待,二进制的第j位中0代表没有写第n门作业,1代表写了第j门作业        {            dp[i]=inf;   //初始化状态为无穷大            for(j=n-1; j>=0; j--)  //分别查找第j门(j+1门),因为要顺着输出所以要从后往前判断,比如有两门作业完成后分数相同,在这种情况下,起初位于前面的作业位于前面            {                int temp=1<<j;   //判断第j门(j+1门);                if(!(i&temp))  continue; //若第j门没有做,跳出循环。                int score=time[i-temp]+a[j].actual-a[j].limit;//最后做第j门作业,对应的被扣分数的为多少,                if(score<0) score^=score;   //不可能存在被扣分数为负,若负则为0;                if(dp[i]>dp[i-temp]+score)    //若最后做第j门作业,所扣的分数少于之前的分数:                {                    dp[i]=dp[i-temp]+score;  //就将此状态作为此状态最优解,                    time[i]=time[i-temp]+a[j].actual;//此状态对应所用时间更新。                    print[i]=j;  //用来记录路径,最后要打印。                }            }        }        printf("%d\n",dp[total-1]);  //n门功课全部做完对应的状态是n个1,即(1<<n)-1,即total-1;        output(total-1); //打印路径要倒过来打印,比如print[total-1]时对应的是最后一门作业做的是哪一门,然后total-1-(1<<print[total-1])对应的是除去倒数第一门作业时,对应的状态    }}
2 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 婴儿自己把眼珠子抠红了怎么办 如果美陆战队员进入台湾那怎么办? 顺产生完小孩吸不通奶怎么办 耐克空军一号白色底发黄怎么办 中行网银u盾丢了怎么办 有人用你的手机号码不停注册怎么办 获得公开你微信头像的权限是怎么办 手机能进的网站电脑进不去怎么办 苹果8p下不了微信怎么办 苹果手机版本过底不能下微信怎么办 手机打开视频跳转到qq是怎么办 淘宝店铺显示服务竟然出错了怎么办 母羊下完羊羔把羊衣吃了怎么办? 移植后56天有黑色东西怎么办 我家的金丝熊浑身都是尿怎么办 一键启动车钥匙丢了怎么办 把爷爷的遗物弄丢了怎么办 如果你娶了一个傻子你怎么办 在国外订机票手机收不到信息怎么办 网上买机票名字写错了怎么办 买机票名字错了一个字怎么办 微店没收到货却显示已收货怎么办? 手机存的照片误删了怎么办 魔兽世界把要用的装备分解了怎么办 邻居家的狗见到我就叫怎么办 我的世界玩的时间长会卡应该怎么办 网易我的世界密码账号都忘了怎么办 我的世界创建世界画面乱码了怎么办 网易我的世界云端存档不够用怎么办 玩刺激战场带耳机声音有延迟怎么办 我的世界手机版狼变色怎么办 我的世界开了光影太阳太刺眼怎么办 我的世界饥饿值掉的慢怎么办 我的世界合装备过于昂贵怎么办 我的世界故事模式屏幕是黑的怎么办 人物只剩下轮廓的图用ps怎么办 两年义务兵考军校分数不够怎么办 大学生兵考上军校后原学籍怎么办 我的世界工业附魔到精准采集怎么办 交换生在台期间遗失通行证怎么办 驾驶证上的号码是士兵证号怎么办