• HDU1074


    HDU1074.Doing Homework

    题意

    给n个作业,每个作业都有一个截止日期,和一个做完所需的时间,超过截止时间写每天扣 1 分, 问最少扣几分可以完成全部作业并输入方案(完成的顺序,相同输出字典序最小)(n<=15)

    分析

    状压dp入门,从数据范围就可以看出状压的思路?n最大15, 考虑二进制0/1表示每门作业的完成情况,则需要2^15,dp[i] : 表示状态i的最有解

    再把状态i中所有作业完成的顺序枚举出来求出最优即可,每次记录一下转移的方向即可

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = (1<<15) + 10;
    
    int dp[maxn];
    int path[maxn];
    int decline[20];
    int cost[20];
    int tme[maxn];
    int n;
    char s[20][105];
    
    void print(int num)
    {
        if(!num)
            return;
        print(num-(1<<path[num]));
        printf("%s
    ",s[path[num]]);
    }
    
    int main()
    {
        int t;
        scanf("%d", &t);
        while(t--)
        {
            scanf("%d", &n);
            for(int i = 0; i < n; i++)
            {
                scanf("%s%d%d", s[i], &decline[i], &cost[i]);
            }
            dp[0] = 0;
            memset(path,0,sizeof(path));
            for(int i = 1; i < (1<<n); i++)
            {
                dp[i]=1e9;
                for(int j = n-1; j >= 0; j--)
                {
                    int temp = (1<<j);
                    if(!(temp & (i)))
                        continue;
                    int ans = tme[i^temp]+cost[j]-decline[j];
                    if(ans<0)
                        ans = 0;
                    if(dp[i] > dp[i^temp]+ans)
                    {
                        dp[i] = dp[i^temp]+ans;
                        tme[i]=tme[i^temp]+cost[j];
                        path[i]=j;
                    }
                }
            }
            printf("%d
    ", dp[(1<<n)-1]);
            print((1<<n)-1);
        }
    }
    View Code
    要么优秀要么生锈
  • 相关阅读:
    System.TypeInitializationException
    Leetcode 884. 两句话中的不常见单词
    Leetcode 5274. 停在原地的方案数
    Leetcode 1254. 统计封闭岛屿的数目
    Leetcode 1262. 可被三整除的最大和
    数据库知识点自我补充
    最大公共连续子序列
    重建二叉树
    KMP算法
    BF算法(模式匹配)
  • 原文地址:https://www.cnblogs.com/Superwalker/p/7865758.html
Copyright © 2020-2023  润新知