andre_joy

导航

hdu 1074

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

题意:有很多作业,没有在规定时间内完成要扣分,一天一分,求最小扣分!

mark:wa了两次,傻了。。把题意理解错了。是超过期限一天就扣一分!!!

   状态压缩dp。dp[i]代表第i个状态的最小罚时,由于本题要输出顺序,所以给dp加上了一个变量,是该状态是由哪个状态来的。

代码:

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

const int M = (1 << 15);

typedef struct
{
    int re;
    int now;
    int pos;
}DP;

typedef struct
{
    char name[110];
    int de;
    int day;
}sub;

DP dp[M+10];
sub s[20];

int main()
{
    int t,n,m;
    int i,j,k;
    int flag[20];
    scanf("%d", &t);
    while(t-- && scanf("%d", &n))
    {
        m = (1 << n);
        for(i = n; i > 0; i--)
            scanf("%s%d%d", s[i].name, &s[i].de, &s[i].day);
        dp[0].re = dp[0].pos = dp[0].now = 0;
        for(i = 1; i < m; i++)
        {
            dp[i].now = 0;
            for(j = 0; j < n; j++)
                if(i & (1 << j)) dp[i].now += s[n-j].day;
            dp[i].re = 0x7fffffff;
        }
        for(i = 0; i < m-1; i++)
        {
            for(j = 0; j < n; j++)
            {
                k = (1 << j);
                if(!(i & k))
                {
                    int sum;
                    sum = dp[i].now+s[n-j].day-s[n-j].de;
                    if(sum < 0) sum = 0;
                    if(dp[i | k].re > dp[i].re+sum)
                    {
                        dp[i | k].re = dp[i].re+sum;
                        dp[i | k].pos = n-j;
                    }
                }
            }
        }
        printf("%d\n", dp[m-1].re);
        i = m-1;
        for(j = n; j > 0; j--)
        {
            flag[j] = dp[i].pos;
            i ^= (1 << (n-dp[i].pos));
        }
        for(i = 1; i <= n; i++)
            printf("%s\n", s[flag[i]].name);
    }
    return 0;
}

posted on 2012-08-19 13:24  andre_joy  阅读(156)  评论(0编辑  收藏  举报