zoukankan      html  css  js  c++  java
  • hdu 1074(状态压缩dp+记录路径)

    题意:给了n个家庭作业,然后给了每个家庭作业的完成期限和花费的实践,如果完成时间超过了期限,那么就要扣除分数,然后让你找出一个最优方案使扣除的分数最少,当存在多种方案时,输出字典序最小的那种,因为题意已经说了家庭作业的名字是按照字典序从小到大输入的,所以处理起来就好多了。

    分析:此题的关键是如何记录路径,具体看代码实现吧!

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    struct node{
        char str[105];
        int dayline;
        int cost;
    }a[20];
    
    struct st{
        int now,pre;//now代表当前状态,pre代表当前状态的前一个状态
        int time;//当前时间
        int score;//当前扣除的分数
        int id;//当前刚做完的作业
    }dp[35000];
    
    int n;
    
    void solve()
    {
        int i,j,max=1<<n,qian,temp,num=0;
        char res[20][105];
        dp[0].now=0;
        dp[0].pre=0;
        dp[0].time=0;
        dp[0].score=0;
        dp[0].id=0;
        for(i=1;i<max;i++)
        {
            dp[i].score=100000000;
            for(j=0;j<=n-1;j++)
            {
                if(i&(1<<j))
                {
                    qian=i-(1<<j);//由qian->i
                    if(dp[qian].time+a[j+1].cost>a[j+1].dayline)
                     temp=dp[qian].time+a[j+1].cost-a[j+1].dayline;
                    else
                     temp=0;
                    //temp用来表示做了当前作业需要扣除的分数
                    if(dp[i].score>=dp[qian].score+temp)//这里要取等号,自己想下为什么?如果去掉,会出现生命结果
                    {
                        dp[i].score=dp[qian].score+temp;
                        dp[i].now=i;
                        dp[i].pre=qian;
                        dp[i].time=dp[qian].time+a[j+1].cost;
                        dp[i].id=j+1;
                    }
                }
            }
        }
        printf("%d
    ",dp[max-1].score);
        int t=max-1;
        while(dp[t].now!=0)//先把结果倒过来
        {
            strcpy(res[num++],a[dp[t].id].str);
            t=dp[t].pre;
        }
        for(i=num-1;i>=0;i--)
         printf("%s
    ",res[i]);
    }
    
    int main()
    {
        int T,i;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            getchar();
            for(i=1;i<=n;i++)
            {
                scanf("%s",a[i].str);
                scanf("%d",&a[i].dayline);
                scanf("%d",&a[i].cost);
                getchar();
            }
            solve();
        }
        return 0;
    }
  • 相关阅读:
    PHP获取文件后缀名的方法有哪些?
    提高mysql千万级数据SQL查询优化30条经验
    关系型数据库和非关系型数据库有哪些?两类常见的数据库的介绍与对比
    什么是外键?为什么要使用外键?
    windows10桌面鼠标右键出现卡顿解决方法
    datawhale数据分析task01
    datawhale爬虫task04
    datawhale爬虫task02
    datawhale爬虫task01
    爬虫实战01——爬取猫眼电影top100榜单
  • 原文地址:https://www.cnblogs.com/jiangjing/p/3450171.html
Copyright © 2011-2022 走看看