[BZOJ 2287/POJ openjudge1009/Luogu P4141] 消失之物
题面:
传送门:http://poj.openjudge.cn/practice/1009/
Solution
DP+DP
首先,我们可以很轻松地求出所有物品都要的情况下的选择方案数,一个简单的满背包DP就好
即:f[i][j]表示前i个物品装满容量为j的背包的方案数.
转移也很简单 f[i][j]=f[i-1][j]+f[i-1][j-w[i]] (i:1~n,j:1~m) (即选和不选的问题)
初始化 f[i][0]=1 (i:[0~n]) (如果背包容量为0,无论如何都有且只有一种方案将其装满)
接下来,考虑用另一个dp来求解在某一物品不放下的方案数
设 g[i][j] 表示第i个物品不放入背包,装满容量为j的背包的方案数
转移为:
g[i][j] = f[n][j] ( j < w[i]) (即当背包容量小于所不放物品的大小时,那么其方案数必然为f[n][j],因为f[n][j]中的所有方案肯定取不到第i个)
= f[n][j] - g[i][j-w[i]]
i:1~n j:1~m
下面那个转移意思即是:
所有的方案总数 减去 包括第i项物品的方案数
因为g[i][j-w[i]]中的每一种情况再装入w[i]即可达到g[i][j]这个状态,而g[i][j]的定义是不装入i的方案数,所以说包括第i项物品的方案能且仅能从g[i][j-w[i]]转移过来
初始化:
g[i][0]=1 (i:[0~n])(背包容量为0时方案有且仅有啥都不要)
这样就可以口头AC了
但是,还有一个要注意的小地方
在%P的意义下, f[n][j]-g[i][j-w[i]]有可能为负数
负数取模的方法为 : (x % P + P)%P
然后就OK啦
Code
//Openjudge 1009:消失之物
//Apr,2ed,2018
//DP+DP
#include<iostream>
#include<cstdio>
using namespace std;
long long read()
{
long long x=0,f=1; char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
const int N=2000+100;
const int M=2000+100;
const int P=10;
char f[N][M],g[M];
int w[N],n,m;
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
w[i]=read(); f[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
{
f[i][j]=f[i-1][j];
if(j-w[i]>=0)
f[i][j]+=f[i-1][j-w[i]];
if(f[i][j]>=P) f[i][j]%=P;
} g[0]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(j<w[i])
printf("%d",g[j]=f[n][j]);
else
printf("%d",g[j]=(f[n][j]-g[j-w[i]]+P)%P);
}
printf("\n");
}
return 0;
}
c++
后记
这种DP+DP的题目还是第一次写,写起来有一点点不熟练
看来我还是需要多学习一个
[BZOJ 2287/POJ openjudge1009/Luogu P4141] 消失之物的更多相关文章
- Luogu P4141 消失之物 背包 分治
题意:给出$n$个物品的体积和最大背包容量$m$,求去掉一个物品$i$后,装满体积为$w\in [1,m]$背包的方案数. 有 N 个物品, 体积分别是 W1, W2, …, WN. 由于她的疏忽, ...
- luogu p4141 消失之物(背包dp+容斥原理)
题目传送门 昨天晚上学长讲了这题,说是什么线段树分治,然后觉得不可做,但那还不是正解,然后感觉好像好难的样子. 由于什么鬼畜的分治不会好打,然后想了一下$O(nm)$的做法,想了好长时间觉得这题好像很 ...
- P4141 消失之物
目录 链接 思路 代码 链接 P4141 消失之物 思路 f[N];//表示删掉物品后能出现容积为i的方案数 a[N];//单纯0-1背包的方案数asd 那么就先求出a[i]来,然后转移就是 if(j ...
- BZOJ.2287.[POJ Challenge]消失之物(退背包)
BZOJ 洛谷 退背包.和原DP的递推一样,再减去一次递推就行了. f[i][j] = f[i-1][j-w[i]] + f[i-1][j] f[i-1][j] = f[i][j] - f[i-1][ ...
- 洛谷P4141 消失之物——背包
题目:https://www.luogu.org/problemnew/show/P4141 竟然是容斥:不选 i 物品只需减去选了 i 物品的方案: 范围原来是2*10^3而不是2*103啊... ...
- 洛谷P4141消失之物(背包经典题)——Chemist
题目地址:https://www.luogu.org/problemnew/show/P4141 分析:这题当然可以直接暴力枚举去掉哪一个物品,然后每次暴力跑一遍背包,时间复杂度为O(m*n^2),显 ...
- 洛谷P4141 消失之物 题解 背包问题扩展
题目链接:https://www.luogu.com.cn/problem/P4141 题目大意: 有 \(n\) 件物品,求第 \(i\) 件物品不能选的时候(\(i\) 从 \(1\) 到 \(n ...
- [洛谷P4141] 消失之物「背包DP」
暴力:暴力枚举少了哪个,下面套一个01背包 f[i][j]表示到了i物品,用了j容量的背包时的方案数,f[i][j]=f[i-1][j]+f[i-1][j-w[i]]O(n^3) 优化:不考虑消失的, ...
- 洛谷P4141消失之物
题目描述 ftiasch 有 N 个物品, 体积分别是 W1, W2, …, WN. 由于她的疏忽, 第 i 个物品丢失了. “要使用剩下的 N – 1 物品装满容积为 x 的背包,有几种方法呢?” ...
随机推荐
- shiro认证流程源码分析--练气初期
写在前面 在上一篇文章当中,我们通过一个简单的例子,简单地认识了一下shiro.在这篇文章当中,我们将通过阅读源码的方式了解shiro的认证流程. 建议大家边读文章边动手调试代码,这样效果会更好. 认 ...
- 剑指Offer(四):重建二叉树
一.前言 刷题平台:牛客网 二.题目 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6, ...
- 计数,dic的创建方式,求九九乘法表
s1='char,python,nihao,ni,ni,python's=s1.split(',')print(s1)s2=list()for i in s: if i not in s2: s2.a ...
- c++ 西安交通大学 mooc 第十三周基础练习&第十三周编程作业
做题记录 风影影,景色明明,淡淡云雾中,小鸟轻灵. c++的文件操作已经好玩起来了,不过掌握好控制结构显得更为重要了. 我这也不做啥题目分析了,直接就题干-代码. 总结--留着自己看 1. 流是指从一 ...
- linux内核输入子系统分析
1.为何引入input system? 以前我们写一些输入设备(键盘.鼠标等)的驱动都是采用字符设备.混杂设备处理的.问题由此而来,Linux开源社区的大神们看到了这大量输入设备如此分散不堪,有木有可 ...
- jvm堆内存和GC简介
最近经常遇到jvm内存问题,觉得还是有必要整理下jvm内存的相关逻辑,这里只描述jvm堆内存,对外内存暂不阐述. jvm内存简图 jvm内存分为堆内存和非堆内存,堆内存分为年轻代.老年代,非堆内存里只 ...
- 如何修改或新增visual studio 的模板
在 visual studio 中添加模板,我这里是新增mvc.net的模板 vs2017在文件夹=>(举例说明,请替换为相应的安装目录) D:\Program Files (x86)\Micr ...
- git commit 代码提交规范
格式 type: description 1. type 类型 type 是 commit 的类别,只允许如下几种标识: fix: 修复bug add: 新功能 update: 更新 refactor ...
- widows安装ffmpeg
首先下载ffmpeg的windows版本https://ffmpeg.zeranoe.com/builds/ 解压到d盘 win+r cmd 说明成功了
- linux(centos8):为prometheus安装grafana(grafana-7.0.3)
一,grafana的用途 1,grafana是什么? grafana 是用 go 语言编写的开源应用, 它的主要用途是大规模指标数据的可视化展现 它是现在网络架构/应用分析中最流行的时序数据展示工具 ...