D - Doing Homework HDU1074 ( 动态规划 + 状态压缩 )

D - Doing Homework

Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u

Submit Status Practice HDU 1074

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.

题目的意思给你n(n<=15)门课程,你要去完成每门课的作业,但是老师给你了完成的期限,超过期限每一天就会扣你一分。问你安排完成作业的顺序使扣分最小。

第一次做状态压缩,参考分析:点击打开链接

dp[i]:表示到达状态i扣去的最小的分数,  sum[i]:表示到达状态i时过去的天数

#include<bits/stdc++.h>
using namespace std;
template<class T>inline T read(T&x)
{
    char c;
    while((c=getchar())<=32)if(c==EOF)return 0;
    bool ok=false;
    if(c=='-')ok=true,c=getchar();
    for(x=0; c>32; c=getchar())
        x=x*10+c-'0';
    if(ok)x=-x;
    return 1;
}
template<class T> inline T read_(T&x,T&y)
{
    return read(x)&&read(y);
}
template<class T> inline T read__(T&x,T&y,T&z)
{
    return read(x)&&read(y)&&read(z);
}
template<class T> inline void write(T x)
{
    if(x<0)putchar('-'),x=-x;
    if(x<10)putchar(x+'0');
    else write(x/10),putchar(x%10+'0');
}
template<class T>inline void writeln(T x)
{
    write(x);
    putchar('\n');
}
//-------ZCC IO template------
const int maxn=1<<20;
const double inf=999999999;
#define lson (rt<<1),L,M
#define rson (rt<<1|1),M+1,R
#define M ((L+R)>>1)
#define For(i,t,n) for(int i=(t);i<(n);i++)
typedef long long  LL;
typedef double DB;
typedef pair<int,int> P;
#define bug printf("---\n");
#define mod  100000000

struct node
{
    char name[150];
    int need;//需要几天来解决
    int length;//老师给的期限
}p[maxn];
int dp[maxn],pre[maxn],sum[maxn];

void to(int s)
{
    if(!s)return ;
    to(s^(1<<pre[s]));
    printf("%s\n",p[pre[s]].name);
}
int main()
{
    int T,n;
    read(T);
    while(T--)
    {
        read(n);
        For(i,0,n)
        {
            scanf("%s%d%d",p[i].name,&p[i].length,&p[i].need);
        }
        memset(sum,0,sizeof(sum));
        int N=1<<n;
        for(int i=1;i<N;i++)
        {
            dp[i]=inf;
            for(int j=0;j<n;j++)
            {
                int tmp=1<<j;if(!(tmp&i))continue;
                int reduce=sum[i^tmp]+p[j].need-p[j].length;
                if(reduce<=0)reduce=0;
                if(dp[i]>=reduce+dp[i^tmp])
                {
                    dp[i]=reduce+dp[i^tmp];
                    pre[i]=j;
                    sum[i]=p[j].need+sum[i^tmp];
                }
            }
        }
        writeln(dp[N-1]);to(N-1);
    }
    return 0;
}
时间: 2024-08-29 02:10:11

D - Doing Homework HDU1074 ( 动态规划 + 状态压缩 )的相关文章

HDU 1074 Doing Homework(DP&#183;状态压缩)

题意  有n个作业要做   给你每个作业的最后期限  和做完这个作业需要的时间  作业每超过最后期限一天就会扣一分  只能把一个作业做完了再做另一个作业  问做完所有作业至少扣多少分 作业最多只有15个  看到这个数字容易想到是状态压缩  dp[i]表示i对应状态的最小扣分  i转换为二进制后为1的位表明该位对应的作业已经做了  为0的位没做  那么dp[i] = min{dp[k] + cost | k为将某一位变成1后等于 i 的状态} 由于要打印路径  所有还需要记录每个状态的上一个状态p

ACM学习历程—HDU1584 蜘蛛牌(动态规划 &amp;&amp; 状态压缩)

Description 蜘蛛牌是windows xp操作系统自带的一款纸牌游戏,游戏规则是这样的:只能将牌拖到比她大一的牌上面(A最小,K最大),如果拖动的牌上有按顺序排好的牌时,那么这些牌也跟着一起移动,游戏的目的是将所有的牌按同一花色从小到大排好,为了简单起见,我们的游戏只有同一花色的10张牌,从A到10,且随机的在一行上展开,编号从1到10,把第i号上的牌移到第j号牌上,移动距离为abs(i-j),现在你要做的是求出完成游戏的最小移动距离. Input 第一个输入数据是T,表示数据的组数.

[POJ 2923] Relocation (动态规划 状态压缩)

题目链接:http://poj.org/problem?id=2923 题目的大概意思是,有两辆车a和b,a车的最大承重为A,b车的最大承重为B.有n个家具需要从一个地方搬运到另一个地方,两辆车同时开,问最少需要搬运几次? 我先想的是我由A车开始搬,搬运能装的最大的家具总重,然后状态压缩记录下搬运了哪些,然后再由B车搬运,状态压缩记录搬运了哪些.以此类推,直到状态满了. 以上方法TLE 然后,实在想不出来了,看了题解:http://blog.csdn.net/woshi250hua/articl

3.4 熟练掌握动态规划——状态压缩DP

从旅行商问题说起—— 给定一个图,n个节点(n<=15),求从a节点出发,经历每个节点仅一次,最后回到a,需要的最短时间. 分析: 设定状态S代表当前已经走过的城市的集合,显然,S<=(1<<n)-1. dp[k][s]——从a走到k,已经经历过的节点集合为s,按照规则走回a所需要的最短时间. 初始化:dp[k][s]=-1 int DP(int K,int S) { if (dp[K][S]!=-1) { return dp[K][S]; } if (K==a &&

【POJ 1170】 Shopping Offers [动态规划 状态压缩 背包][离散化]

POJ - 1170 Shopping Offers 放假打题 sufu 看完题我是懵比的 这....  emmmmm   瓜想了半个小时之后我选择狗带 然后点开链接 装压+dp!!!!哦!!!!!!巧妙!!!! 就先把目标状态还有各个优惠的状态处理好 然后就是一个完全背包处理用优惠 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int S=100+5,N=10,P=10000+5,C=1000+5; 4 int sale[S

Doing Homework HDU - 1074 状态压缩

#include<iostream> #include<cstring> #include<cstdio> #include<string> #include<cmath> using namespace std; const int INF=0x3f3f3f3f; const int MAXN=(1<<15)+5; const int MOD=1e9+7; int dead[20],cost[20]; int dp[MAXN],t[

[ZOJ 3662] Math Magic (动态规划+状态压缩)

先贴代码,晚上回去说 1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #include <cmath> 5 #include <map> 6 #include <iterator> 7 #include <vector> 8 using namespace std; 9 typedef long long LL; 10 11 int n,m

状态压缩-----HDU1074 Doing Homework

HDU1074 Doing Homework 题意:给了n个家庭作业,然后给了每个家庭作业的完成期限和花费的实践,如果完成时间超过了期限,那么就要扣除分数,然后让你找出一个最优方案使扣除的分数最少,当存在多种方案时,输出字典序最小的那种,因为题意已经说了家庭作业的名字是按照字典序从小到大输入的,所以处理起来就好多了. 分析:此题的关键是如何记录路径,具体看代码 1 #include <iostream> 2 #include <cstdio> 3 #include <cstr

HDU1074 Doing Homework 状态压缩dp

题目大意: 根据完成任务的截止时间,超时一天罚1分,求完成所有任务后的最小罚时 这里n最大为15,可以利用状态压缩来解决问题 1 /* 2 首先要明白的一点是状态1/0分别表示这件事做了还是没做 3 而1/0的位置表示这是哪一件事 4 比如说 5 可以表示为101,那么表示第一个和第三个任务已经完成 5 而dp[5]表示第一个和第三个任务完成所花费的最短时间 6 而状态5(101)是从状态1(001)或者状态4(100)转移过来的 7 也就是说我们总是可以通过一个较小的状态不断递推一个较大状态的