zoj 3812 状压dp
转载:http://blog.csdn.net/qian99/article/details/39138329
题意:给出n个物品,每个物品有两种属性Wi,Ti,有q组查询,每组查询要求在n个物品中选出一些,并使得两个属性的和为Mi,Si。
思路:刚开始看感觉是神题,后来仔细想了想,其实本质上就是个背包。最裸着写的话,那么就是dp[i][j][k]表示使用前i个物品,是否可以凑出第一个属性j,第二个属性k,要输出方案的话记录一下路径就可以了。一开始这么写了一发,加了一些乱七八糟的优化,还是会T。虽然这题时限还算宽,但这么写复杂度还是太高了。考虑到第一个属性最多只有50,那么可以用一个二进制数来表示是否能凑出第一个属性的情况,即:第i位为1表示可以凑出i。使用这种方法的好处是对于物品i可以直接算出第一种属性的组合情况,枚举一下新增的位,更新一下结果就行了。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-8
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 400 + 10;
const int M = 51;
short ans[200010][52];
ull f[200010];
int W[maxn],T[maxn];
map<ull,int>mp;
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
for(int i = 1;i <= M + 1;++i)
mp[1LL<<(i-1LL)] = i;
int t,n,q;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&q);
memset(ans,0,sizeof(ans));
memset(f,0,sizeof(f));
f[0] = 1;
ull v,x;
for(int i = 1;i <= n;++i)
{
scanf("%d%d",&W[i],&T[i]);
for(int j = 200000;j >= T[i];--j)
{
v = f[j]; //f[j]表示第二个属性为j时,能够凑出的第一个属性的集合,用一个二进制数表示,第i位为1表示可以凑出这个数
f[j] |= (f[j - T[i]]<<W[i]) & ((1LL<<M+1) - 1); //计算使用当前物品能够得到的新的集合,在集合f[j - T[i]]添加W[i]的物品,
//即原来能得到的每个值加上W[i],等价于将其左移W[i]位
for(ull k = v ^ f[j];k ; k &= k-1) //枚举新增加的集合
{
x = (k ^ (k - 1)) & k;
ans[j][mp[x] - 1] = i; //将新增的位置更新,记录是使用了哪个物品达到的这个状态
}
}
}
int m,s,p;
for(int i = 0;i < q;++i)
{
scanf("%d%d",&m,&s);
if(!ans[s][m])
puts("No solution!");
else
{
printf("%d",ans[s][m]);
p = ans[s][m];
m -= W[p];
s -= T[p];
while(m)
{
p = ans[s][m];
printf(" %d",p);
m -= W[p];
s -= T[p];
}
puts("");
}
}
}
return 0;
}
zoj 3812 状压dp的更多相关文章
- Problem Arrangement ZOJ - 3777(状压dp + 期望)
ZOJ - 3777 就是一个入门状压dp期望 dp[i][j] 当前状态为i,分数为j时的情况数然后看代码 有注释 #include <iostream> #include <cs ...
- ZOJ 3306 状压dp
转自:http://blog.csdn.net/a497406594/article/details/38442893 Kill the Monsters Time Limit: 7 Seconds ...
- ZOJ - 3777(状压dp)
The 11th Zhejiang Provincial Collegiate Programming Contest is coming! As a problem setter, Edward i ...
- Most Powerful(ZOJ 3471状压dp)
题意:n个原子,两两相撞其中一个消失,产生能量,给出任意两原子相撞能产生的能量,求能产生的最大能量. 分析:dp[i]表示情况为i时产生的最大能量 /*#include <map> #in ...
- Survival(ZOJ 2297状压dp)
题意:有n个怪,已知杀死第i个怪耗费的血和杀死怪恢复的血,和杀死boss耗的血,血量不能超过100,若过程中血小于0,则失败,问 是否能杀死boss(boss最后出现). 分析:就是求杀死n个怪后剩余 ...
- Long Dominoes(ZOJ 2563状压dp)
题意:n*m方格用1*3的方格填充(不能重叠)求有多少种填充方法 分析:先想状态,但想来想去就是觉得不能覆盖所有情况,隔了一天,看看题解,原来要用三进制 0 表示横着放或竖放的最后一行,1表示竖放的中 ...
- Travel(HDU 4284状压dp)
题意:给n个城市m条路的网图,pp在城市1有一定的钱,想游览这n个城市(包括1),到达一个城市要一定的花费,可以在城市工作赚钱,但前提有工作证(得到有一定的花费),没工作证不能在该城市工作,但可以走, ...
- ZOJ 3723 (浙大月赛)状压DP
A了一整天~~~终于搞掉了. 真是血都A出来了. 题目意思很清楚,肯定是状压DP. 我们可以联系一下POJ 1185 炮兵阵地,经典的状压DP. 两道题的区别就在于,这道题的攻击是可以被X挡住的,而 ...
- ZOJ 3777 - Problem Arrangement - [状压DP][第11届浙江省赛B题]
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3777 Time Limit: 2 Seconds Me ...
随机推荐
- [Swift通天遁地]一、超级工具-(13)使用PKHUD制作各种动态提示窗口
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- 【工具】---- json-server基本使用
一.概念 在开发过程中,前端通常需要等待后端开发完接口后,再调用接口渲染相应的数据,这会影响开发效率.而json-server的作用就是为了解决前后端并行开发的痛点,在本地模拟后端接口用来测试前端效果 ...
- C#---数据库访问通用类、Access数据库操作类、mysql类 .
//C# 数据库访问通用类 (ADO.NET)using System;using System.Collections.Generic;using System.Text;using System. ...
- 309 Best Time to Buy and Sell Stock with Cooldown 买股票的最佳时间含冷冻期
Say you have an array for which the ith element is the price of a given stock on day i.Design an alg ...
- [转]Windows Azure平台简介(一):定位与产品结构
本文转自:http://blog.csdn.net/azurechina/article/details/5592236 http://blogs.msdn.com/b/azchina/archive ...
- 观察者模式(observer)c++实现
1意图 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 2别名 依赖(Dependents), 发布-订阅(Publish-Subscribe ...
- 面试中的一些小问题之html5和html4的区别?
HTML5建立的一些新规则: 新特性应该基于HTML.CSS.DOM.JavaScript: 减少对外部插件的需求,如flash将会用video标签和audio标签代替: 更加优秀的错误处理: 更多取 ...
- typeloadexception 方法实现中引用的声明不能是final方法
问题描述: 1. 修改了DVSNetClient项目,其依赖类库CameraDSP没有改动.CameraDSP_DVSNetClient.dll的版本编号和文件编号由1.0.0.0变为1.0.1.0. ...
- 如何创建C# Closure?
JavaScript中一个重要的概念就是闭包,闭包在JavaScript中有大量的应用,但是你知道么?C#也可以创建Closure.下面就介绍一下如何在C#中创建神奇的闭包. 在这之前,我们必须先知道 ...
- 判断excel是否包含隐藏sheet
Workbook workbook =new XSSFWorkbook("D:\\文档1.xlsx"); System.out.println(workbook.isSheetHi ...