状态压缩dp
在看到这个毒瘤题目之前我一直觉得吧,状态里头怎么能够有指数级别的变量呢???
然后我就花了至少一个小时的时间想有没有更好的方法“让状态转移有序化”。虽然数据范围很小但我就是不想这样搞。结束后我去问了老师才知道这居然是很常见的操作。一般变量范围在指数级别的都能用状态压缩来减少……减少什么东西呢……反正都能压缩,要是不能压缩你也超时。
状态压缩的意思是把一些需要多个二进制位保存的状态利用一个整数来保存,避免了位数不同时出现的尴尬局面。然而只知道这个什么用都没有。
下面来看看例题吧。
题目描述
小c现在有M(1≤M≤20)道题目不会写,他决定找大牛们要代码。
这N(1≤N≤100)位大牛每人都写了若干题,并且提出了各自要求的报酬,给钱就能获得他的所有代码。
小c虽然是笨蛋,但已经不会随便提交别人的代码了,他只提交自己能看懂的代码。
然而,大牛们的代码风格千奇百怪,如果智力不达标,是根本看不懂的。
所以小c还要去上智力提升课程。一节课能提升1点智力,学费是K(1≤K≤109)元。
(他现在的智力为0)
他希望花最少的钱解决所有题目。
输入
第一行,整数N,M,K.
下面共2N行,每两行描述一位大牛.
第1行,整数xi,qi,mi,分别表示报酬要求,智力要求,解决的题目数
(1 ≤ xi,qi ≤ 109;1 ≤ mi ≤ M)
第2行,mi个整数,表示他解决的题。题目标号为1到M
输出
一个整数,表示解决所有题目需要的最少花费。若无法完成,输出-1
样例1
输入
2 2 1
100 1 1
2
100 2 1
1
输出
202
样例2
输入
1 2 1
1 1 1
1
输出
-1
样例3
输入
3 2 5
100 1 1
1
100 1 1
2
200 1 2
1 2
输出
205
大概就是这样,除了智商和钱好像都没有什么有序的变量可供作为状态,所以就只能捡好的用咯。
因为我们只关心在所有题都做好的情况下的智商,所以我们可以使大牛按照智商排序以求结束时的智商是在只雇用前面这些人的情况下智商最低的,也因为这样,我们不把智商纳入状态中,因为这样会让推进变得无序。虽然看似有些无脑但是这样对于最优解的处理就很好搞了。
用一个整数保存做了什么题,数量级是$$2^{20}$$,大概在两百万的样子,开还是开的下的。
确定了状态剩下的就是一个0-1背包问题了。但是还有一个智商需要解决,由于我们只关心最终把所有题完成也就是(1<<m)-1这个状态时的智商,只需要将当前人的智商(也就是最低智商)乘以课的价钱加上状态就好了。虽然考试的时候几乎想不到就是了。
#include<bits/stdc++.h>
using namespace std;
const long long inf=1900000000000000000;
long long n,m,k,can,ans=inf;
long long dp[(1<<20)-1];
struct per{
long long x,m,sol;
int q;
}cal[105];
bool cmp(per a,per b){
return a.q<b.q;
}
int main(){
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
cin>>cal[i].x>>cal[i].q>>cal[i].m;
for(int j=1;j<=cal[i].m;j++){
cin>>can;
cal[i].sol|=1<<can-1;
}
}
sort(cal+1,cal+n+1,cmp);
for(int i=1;i<=(1<<m)-1;i++)
dp[i]=inf;
for(int i=1;i<=n;i++){
for(int j=(1<<m)-1;j>=0;j--)
if(dp[j]<inf&&dp[j|cal[i].sol]>dp[j]+cal[i].x)
dp[j|cal[i].sol]=dp[j]+cal[i].x;
ans=min(ans,dp[(1<<m)-1]+cal[i].q*k);
}
// cout<<dp[1]<<" "<<dp[2]<<" "<<dp[3]<<'\n';
if(ans==inf)
cout<<-1;
else cout<<ans;
return 0;
}
原文地址:https://www.cnblogs.com/Schwarzkopf-Henkal/p/11759372.html
- 关于oracle invalid components问题的解决(28天)
- 11g升级性能问题之一 重建user_synonyms (笔记27天)
- 数据库shutdown之后无法启动的问题 (46天)
- 关于oracle里的process总结(45天)
- 通过top命令抓取cpu高消耗的sql (44天)
- 关于字符串匹配查找的总结(43天)
- 一条sql语句导致的数据库宕机问题及分析(42天)
- 外部表的导入导出问题 (41天)
- 当我们和计算机交互时,它看到的是什么?
- 一条sql语句“导致”的数据库宕机问题及分析 (38天)
- rman数据备份恢复学习笔记(49天)
- 虚拟专用数据库VPD应用 (48天)
- 关于创建视图的问题(48天)
- 性能调优之redo切换频率(47天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法