HDU 1074 动态规划

HDU 1074

慢慢写了半个多小时的dp,思路很清楚,二进制保存状态,然后如果这个状态为0,就添上1转移,并且记录路径,做之前一定要想好要记录哪些东西,由于一个状态不管cost是啥,总之是一样的。因为不管什么状态,加到这一步,总天数都是一样的。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
int vis[1<<15+5];
struct Work
{
    char name[110];
    int deadline;
    int cost;
}date[20];

struct Go
{
    int pre;
    int reduce;
    int cost;
}dp[1<<15+5];

void out(int temp)
{
    int tempnext=dp[temp].pre;
    if (tempnext!=-1)
    {
        int a=(int)(log(temp-tempnext)/log(2));
        out(tempnext);
        printf ("%s\n",date[a].name);
    }
    else return;
}

int main()
{
    int T,n;
    scanf ("%d",&T);
    while(T--)
    {
        scanf ("%d",&n);
        memset(vis,0,sizeof(vis));
        memset(dp,0,sizeof(dp));
        for (int i=0;i<n;i++)
        {
            scanf ("%s%d%d",date[i].name,&date[i].deadline,&date[i].cost);
        }
        int maxdp=(1<<n)-1;
        dp[0].pre=-1;
        dp[0].reduce=0;
        dp[0].cost=0;
        for (int i=0;i<maxdp;i++)
        {
            for (int j=0;j<n;j++)
            {
                int cur=1<<j;
                if ((i&cur)==0)
                {
                    int curnext=cur|i;
                    int day=dp[i].cost+date[j].cost;
                    dp[curnext].cost=day;
                    int rreduce=day-date[j].deadline;
                    if (rreduce<=0) rreduce=0;
                    rreduce+=dp[i].reduce;
                    if (vis[curnext])
                    {
                        if (rreduce<dp[curnext].reduce)
                        {
                            dp[curnext].reduce=rreduce;
                            dp[curnext].pre=i;
                        }
                    }
                    else
                    {
                        vis[curnext]=1;
                        dp[curnext].pre=i;
                        dp[curnext].reduce=rreduce;
                    }
                }
            }
        }
        printf ("%d\n",dp[maxdp].reduce);
        out(maxdp);
    }
    return 0;
}

时间: 2024-11-08 06:41:59

HDU 1074 动态规划的相关文章

[2016-03-28][HDU][1074][Doing Homework]

时间:2016-03-28 18:46:36 星期一 题目编号:[2016-03-28][HDU][1074][Doing Homework] 题目大意:给定n门科作业的期限时间和完成耗时,每科每超过一天就扣一份,求最少扣分数 分析:n只有15,二进制枚举,状态压缩,枚举每种科目完成的状态,更新下一个状态,求最小值 #include <cstring> #include <cstdio> using namespace std; const int maxstu = 1 <&

HDU 1074 Doing Homework(状压DP)

Problem 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 r

FatMouse&#39;s Speed hdu 1160(动态规划,最长上升子序列+记录路径)

http://acm.hdu.edu.cn/showproblem.php?pid=1160 题意:现给出老鼠的体重与速度,要求你找出符合要求的最长子序列.       要求是 W[m[1]] < W[m[2]] < ... < W[m[n]](体重) && S[m[1]] > S[m[2]] > ... > S[m[n]] (速度) 分析:有两个变量的话比较不好控制,自然需要先排序.再仔细思考的话,觉得和之前做的防御导弹有点类似,都是求最多能有几个符合

hdu 1074 状态压缩

http://acm.hdu.edu.cn/showproblem.php?pid=1074 我们可以断定状态的终止态一定是n个数全部选完的情况,那么它的前一个状态是什么呢,一定是剔除任一门课程后的n种状态. 例如 dp[全选了]=min{(dp[除了math都做了]+math的超时天数),(dp[除了computer都做了]+computer的超时天数),(dp[除了english都做了]+english的超时天数)}那么接下来的dp状态依然如此. 好了,接下来,我们该如何去思考了,这个题目共

HDU 1074

http://acm.hdu.edu.cn/showproblem.php?pid=1074 每个任务有一个截止日期和完成时间,超过截止日期一天扣一分,问完成全部任务最少扣几分,并输出路径 最多15个任务,状态压缩一下进行dp,输出路径的话要记录每种状态的前驱,存起来逆序输出 #include <iostream> #include <cstdio> #include <cstring> #include <map> using namespace std;

HDU 1074:Doing Homework(状压DP)

http://acm.hdu.edu.cn/showproblem.php?pid=1074 Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7704    Accepted Submission(s): 3484 Problem Description Ignatius has just come bac

C - Monkey and Banana HDU 1069( 动态规划+叠放长方体)

C - Monkey and Banana Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1069 Description A group of researchers are designing an experiment to test the IQ of a monkey. They will hang a banana at the roof

HDU 1074 Doing Homework DP 状压DP

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目描述: 给你所有课程的截止时间和工作时长, 一次只能做一种作业, 问最少罚时几天 N <= 15 解题思路: 由于N很小, 所以第一反应就是状压DP, 我们可以用一个15位二进制数来表示各个课程做完还是没做完, 然后从 S 从 1 到 1 << N 枚举 i 从 1 到 N 枚举, 如果S & (1<<i) 有效则说明i 属于情况 S, 这样我们从上一步S -

hdu 2571 动态规划

简单的动态规划 #include<cstdio> #include<cstring> #define Max(a,b) (a>b?a:b) int dp[21][1001]; int map[21][1001]; int main() { int t; scanf("%d",&t); while(t--) { int m,n; scanf("%d%d",&n,&m); for(int i=1;i<=n;i+