[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 的背包,有几种方法呢?” ...
随机推荐
- 再解决不了前端加密我就吃shi
参考文章 快速定位前端加密方法 渗透测试-前端加密测试 前言 最近学习挖洞以来,碰到数据做了加密基本上也就放弃了.但是发现越来越多的网站都开始做前端加密了,不论是金融行业还是其他.所以趁此机会来捣鼓一 ...
- Prime Path(POJ - 3126)【BFS+筛素数】
Prime Path(POJ - 3126) 题目链接 算法 BFS+筛素数打表 1.题目主要就是给定你两个四位数的质数a,b,让你计算从a变到b共最小需要多少步.要求每次只能变1位,并且变1位后仍然 ...
- Linux ALSA 音频库 配置和使用
ALSA应用库是核心功能,而alsa-utils是一些工具功能集合库.单纯地播放一个wav文件,使用alsa-utils即可,如果还需要合成音频.调试音频质量,那么就需要ALSA应用库. 欲安装使用A ...
- 026 01 Android 零基础入门 01 Java基础语法 03 Java运算符 06 if-else条件结构
026 01 Android 零基础入门 01 Java基础语法 03 Java运算符 06 if-else条件结构 本文知识点:Java中的if-else条件结构语句 上文回顾--if条件结构 如果 ...
- Android设备上的逐像素碰撞检测
介绍 我正在我的Android设备上开发一款游戏,不用说,因为我想要接触到尽可能多的用户,我做到了 省略了硬件加速.因此,我需要编写能够在大多数设备上运行的最快的代码.我从一个简单的表面视图开始 并使 ...
- [学习笔记] Tarjan算法求强连通分量
今天,我们要探讨的就是--Tarjan算法. Tarjan算法的主要作用便是求一张无向图中的强连通分量,并且用它缩点,把原本一个杂乱无章的有向图转化为一张DAG(有向无环图),以便解决之后的问题. 首 ...
- 学习WebDav
目录 前言 初识WebDav 有哪些支持webdav的网盘? WebDAV的特性和优势 服务端的搭建 调用WebDav接口 PROPFIND方法 PROPPATCH方法 MKCOL方法 PUT方法 G ...
- 炉石传说酒馆战棋一键拔线(windows)
小编的业余游戏之一<炉石传说>,这里分享的是现在很火的游戏拔线(跳过约20秒的战斗动画),用夜吹的话说,注意,不是"日你大坝",是"整活",哈哈.小 ...
- day20 Pyhton学习 面向对象-类与类之间的关系
一.类与类之间的依赖关系 class Elphant: def __init__(self, name): self.name = name def open(self, ref): print(&q ...
- Java改写重构第2版第一个示例
写在前面 <重构:改善既有代码的设计>是一本经典的软件工程必读书籍.作者马丁·福勒强调重构技术是以微小的步伐修改程序. 但是,从国内的情况来而论,"重构"的概念表里分离 ...