HDU 1074

1 篇文章 0 订阅

本菜表示开始做的时候完全不会啊。。。然后之后貌似听到听ZRY大神说什么状态压缩DP,然后就又想了1天,还是不会。。。然后搜索了一下,各种看不懂。。。只看到一句话,全部枚举。全部?不会超时?我真心太菜了,想了很久很久。。。终于搞懂了。。。

然后各种栈溢出,发现数组开小了。。。然后就开暴力了点。。。太不仔细了,切记切记

---------继续在ACM的道路上爬行。。。

#include<stdio.h>
#include<stdlib.h>
struct xx
{
    char name[105];
    int d,c;
}sub[20];
struct xxx
{
     int path[20],cost,time;
}dp[1<<16];
int main()
{
    int i,j,t,k,x,n,head,tail,que[1<<16],temp;
    scanf("%d",&t);
    while(t>0)
    {
        t--;
        memset(dp,-1,sizeof(dp));
        memset(que,0,sizeof(que));
        scanf("%d",&n);
        head=0;tail=-1;
        for(i=1;i<=n;i++)
        {
            scanf(" %s%d%d",sub[i].name,&sub[i].d,&sub[i].c);
            tail++;k=1<<(i-1);que[tail]=k;
            dp[k].path[0]=1;
            dp[k].path[1]=i;
            dp[k].time=sub[i].c;
            temp=sub[i].d-dp[k].time;
            if(temp>=0)dp[k].cost=0;
            else                 dp[k].cost=-temp;
        }
        while(head<=tail)
        {
            k=que[head];
            head++;
            for(i=1;i<=n;i++)
            {
                j=1<<(i-1);
                if((j&k)!=0)continue;
                x=j+k;
                temp=sub[i].d-(dp[k].time+sub[i].c);
                if(temp>=0)temp=0;
                if(dp[x].time==-1||dp[x].cost>dp[k].cost-temp)
                {
                    if(dp[x].time==-1){tail++;que[tail]=x;}
                    dp[x].time=dp[k].time+sub[i].c;
                    dp[x].cost=dp[k].cost-temp;
                    for(j=0;j<=dp[k].path[0];j++)dp[x].path[j]=dp[k].path[j];
                    dp[x].path[0]++;
                    dp[x].path[j]=i;
                }
            }
        }
        k=0;
        for(i=1;i<=n;i++)k+=1<<(i-1);
        printf("%d\n",dp[k].cost);
        for(i=1;i<=n;i++)
        printf("%s\n",sub[dp[k].path[i]].name);
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值