当前位置: 首页 > news >正文

HDU1074 Doing Homework(状压dp)

题意:给定有n门课的作业,每门课交作业有截止时间,和完成作业所花费的时间,如果超过规定时间完成,每超过一天就会扣1分,求一个做作业顺序要求扣的分数最少。


思路:因为数据最大是15,可以使用二进制来表示所有完成的状况,比如二进制位1001,代表第1和第4科目的作业完成,第2第3没有完成,那么从0到(1<<n)其二进制就是所有的状态了。首先枚举所有的状态,然后枚举每一门课,假如判断第i门课是否完成可以用1<< i & (当前状态)来判断,然后去更新上次的状态+上完这门课完成所花费的最小分数,dp记录状态路径,最后输出即可。

 

AC代码:

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<queue>
 7 #include<cstdio>
 8 #include<stack>
 9 #include<unordered_map>
10 #define inf 0x3f3f3f3f
11 using namespace std;
12 typedef long long ll;
13 const int maxn = (1<<15)+5;
14 struct node{
15     string name;
16     int end;
17     int cost;
18 }g[35];
19 struct node1{
20     int time;
21     int val;
22     int last;
23     int cur;
24 }dp[maxn];
25 int m,n; 
26 int main(){
27     int t;
28     cin>>t;
29     while(t--){
30         int n;
31         scanf("%d",&n);
32         memset(dp,0,sizeof(dp));
33         for(int i = 1;i<=n;i++) {
34             cin>>g[i].name ;
35             cin>>g[i].end>>g[i].cost; 
36         }
37         int up = 1<<n;
38         for(int i = 1;i<up;i++){
39             dp[i].val = 1<<30;//设置花费的最大值 
40             for(int j = n;j>=1;j--){
41                 int temp = 1<<(j-1);//枚举第j门课是否完成 
42                 if(i & temp){//如果完成 
43                     int last = i - temp;//last为完成第j门课作业之前的状态 
44                     int s = dp[last].time + g[j].cost - g[j].end ;//完成第j门课所需要的花费 
45                     if(s<0) s = 0;
46                     if(dp[last].val + s <dp[i].val ){//如果扣分少于当前的i状态,则进行更新 
47                         dp[i].cur = j; //i状态最后完成的科目是j 
48                         dp[i].val = dp[last].val + s;//更新到i状态扣的分数 
49                         dp[i].time = dp[last].time + g[j].cost;//i更新到i状态的最小时间 
50                         dp[i].last = last; //i状态的上一个状态进行更新 
51                     } 
52                 }
53             }
54         }
55         stack<int> s;
56         int temp = up - 1;
57         printf("%d
",dp[temp].val);//up-1为完成的状态 
58         while(temp){
59             s.push(dp[temp].cur);//把路径依次读入栈中 
60             temp = dp[temp].last;
61         }
62         while(!s.empty()){
63             cout<<g[s.top()].name<<endl;
64             s.pop();
65         } 
66     }
67     return 0;
68 }

相关文章:

  • 前端面试题合集
  • Python均匀分布和三角形分布
  • IT行业面试技巧,90%的人都不知道
  • 数值处理--特征工程
  • java-net-php-python-springboot校园招聘系统计算机毕业设计程序
  • 火到爆的扩散模型(Diffusion Model)帮你具象化幻想世界
  • Nature子刊 | 空间转录组技术及其发展方向
  • 通关算法题之 ⌈字符串⌋
  • python中的import详解
  • 计算机毕业设计Java校园内推系统(系统+源码+mysql数据库+lw文档)
  • 偶数科技:基于OushuDB的新一代云原生湖仓一体为企业助力
  • 【论文笔记】DEEP FEATURE SELECTION-AND-FUSION FOR RGB-D SEMANTIC SEGMENTATION
  • JAMA Neurology:帕金森病跨疾病阶段的新兴神经成像生物标记物
  • LeetCode简单题之按身高排序
  • 从源码角度看React-Hydrate原理
  • 让Linux工作站以非图形化界面的模式启动
  • Ubuntu记住git账号密码
  • Hbase API
  • 微服务框架 SpringCloud微服务架构 22 DSL 查询语法 22.2 全文检索查询
  • 基于改进量子粒子群算法的电力系统经济调度(Matlab代码实现)
  • 电加热油锅炉工作原理_电加热导油
  • 大型电蒸汽锅炉_工业电阻炉
  • 燃气蒸汽锅炉的分类_大连生物质蒸汽锅炉
  • 天津市维修锅炉_锅炉汽化处理方法
  • 蒸汽汽锅炉厂家_延安锅炉厂家
  • 山西热水锅炉厂家_酒店热水 锅炉
  • 蒸汽锅炉生产厂家_燃油蒸汽发生器
  • 燃煤锅炉烧热水_张家口 淘汰取缔燃煤锅炉
  • 生物质锅炉_炉
  • 锅炉天然气_天燃气热风炉