01二重退背包+组合数学——cf1111d】的更多相关文章

退背包进阶,还是挺难想的 /* dp1[k]表示取到体积k的方案数 dp2[i][j][k]表示左侧必选ij的情况下,取到体积k的方案数 dp2[i][j][k]=dp1[k]-左侧不选ij的方案数 但是这样比较难搞,我们把状态转换一下,dp2[i][j][k]表示左侧不选i,j,取到k的方案数 这样要两层退背包来解决 状态前两维可以直接压缩,用ans[i][j]来保存答案,复杂度O(52*52*n) */ #include<bits/stdc++.h> using namespace std…
题目: Codeforces1111D 翻译: [已提交至洛谷CF1111D] 有一个恶棍的聚居地由几个排成一排的洞穴组成,每一个洞穴恰好住着一个恶棍. 每种聚居地的分配方案可以记作一个长为偶数的字符串,第\(i\)个字符代表第\(i\)个洞里的恶棍的类型. 如果一个聚居地的分配方案满足对于所有类型,该类型的所有恶棍都住在它的前一半或后一半,那么钢铁侠可以摧毁这个聚居地. 钢铁侠的助手贾维斯有不同寻常的能力.他可以交换任意两个洞里的野蛮人(即交换字符串中的任意两个字符).并且,他可以交换任意次.…
退背包就是限制某一件物品不可取的方案数 先做出无限制的方案数,然后对于当前不可取的物品,dp2[j]表示不取改物品情况下,取得体积为j的方案数 有状态方程 dp2[j]=dp1[j]-dp2[j-w[i]] 即无限制下取到体积j的方案数 - 有限制下取得体积j-w[i]的方案数(还有w[i]的体积用来装第i件物品,即这种状态时必选i的方案数) #include<bits/stdc++.h> using namespace std; #define maxn 2005 long long n,m…
口胡一种别的解法: 三重退背包,g1[j]k]表示不选x的选了j件物品,体积为k的方案数,g[0][0] = 1 , g1[j][k]=dp[j][k]-g1[j-1][k-a[x]] 然后按这样再退三层,最后看g3[10][87]的方案数是否非0即可,这样复杂度是O(50*50*50*10*87) 如果直接枚举删掉的数,然后用可行性二维01背包做 复杂度是O(50*50*50)*O(n*10*87) 再加上bitset优化第二维 复杂度/32 ,由于n比较小,所以也差不多 /* 在n个数里找到…
01分数规划+背包dp 将分式下面的部分向右边挪过去,通过二分答案验证, 注意二分答案中如果验证的mid是int那么l=mid+1,r=mid-1,double类型中r=mid,l=mid; 背包dp中注意所有大于W的要通过min和max将答案归于W,通过dp得到该种情况的最大结果,不能用贪心 #include<bits/stdc++.h> #define rep(i,x,y) for(register int i=x;i<=y;i++) #define dec(i,x,y) for(r…
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][j-w[i]] //1136kb 56ms #include <cstdio> #include <cctype> #include <cstring> #define gc() getchar() const int N=2005; int w[N],f[N],g[N];…
要点 优质题解 因为只有某type坏人全部分布在同一撇时,才能一次消灭.所以题目安排完毕后一定是type(x)和type(y)占一半,其余占另一半. 实际情况只有52*52种,则预处理答案 枚举某两种,并连续两次使用退背包得到无排列的方案数,真·答案是有排列的,乘上一个排列数即可,而根据式子,排列数恰好与方案细节无关,是个与\(|s|\)和全部\(cnt[i]\)有关的定值 const int maxn = 1e5 + 5; const int mod = 1e9 + 7; string s;…
Codeforces1111D 退背包+组合数 D. Destroy the Colony Description: There is a colony of villains with several holes aligned in a row, where each hole contains exactly one villain. Each colony arrangement can be expressed as a string of even length, where the…
/* 要求把a数组分成两个集合,两个集合人数最多差1,并且元素之和的差尽可能小 那只要把所有可行的列出来即可 01二维背包,即体积是个二维数据,那么我们的背包状态也应该设为二维 dp[j][k]设为 有j个人,体积为k的状态是否可行 第一维上限是人数的一般,第二维上限是元素总和的一半 */ #include<iostream> #include<cstring> #include<cstdio> using namespace std; ]; ][*]; int mai…
第一次知道这种背包还能退的.... 我们用dp[ i ]表示选取若干个物品重量到达 i 的方案数. 如果我们g[ i ]表示不用第 x 个物品的, 然后选若干其他的物品到达 i 的方案数. if(i < cnt[ x ]) g[ i ] = dp[ i ] else  g[ i ] = dp[ i ] - g[ i - cnt[ x ] ] 这样退一次就能删一个物品, 这个题目退两次就可以了. 一共只有52 × 52 / 2个本质不同的询问, 预处理一下. #include<bits/stdc…
就是01分数规划的思路,只不过当把w[i]-r*t[i]>0的选完以后如果w值还没达到要求,那就再01背包dp一下就好了(dp时w值>W的时候就存在W里就不会爆内存了). (跑得很慢..大概是二分的姿势有问题...) (貌似还有直接dp的做法?不会) #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #incl…
/* 给定辩控双方给每个人的打分p[i],d[i], dp[j][k]表示前i个人有j个被选定,选定的人的辩控双方打分差之和是k,此状态下的最大辩控双方和 按01背包做,体积一维是1,体积二维是辩控双方打分差,价值是辩控双方打分和 要求体积一维不得超过m,体积二维在体积一维=m的情况下最小 状态转移方程:dp[j][k]=max(dp[j][k],dp[j-1][k-(a[i]-b[i])]+a[i]+b[i]) */ #include<iostream> #include<cstrin…
2287: [POJ Challenge]消失之物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 657  Solved: 382[Submit][Status][Discuss] Description ftiasch 有 N 个物品, 体积分别是 W1, W2, ..., WN. 由于她的疏忽, 第 i 个物品丢失了. “要使用剩下的 N - 1 物品装满容积为 x 的背包,有几种方法呢?” -- 这是经典的问题了.她把答案记为 Count(…
包子凑数(蓝桥杯) 感谢:@ Statusrank 题目链接(点击) 题目描述 小明几乎每天早晨都会在一家包子铺吃早餐.他发现这家包子铺有N种蒸笼,其中第i种蒸笼恰好能放Ai个包子.每种蒸笼都有非常多笼,可以认为是无限笼. 每当有顾客想买X个包子,卖包子的大叔就会迅速选出若干笼包子来,使得这若干笼中恰好一共有X个包子.比如一共有3种蒸笼,分别能放3.4和5个包子.当顾客想买11个包子时,大叔就会选2笼3个的再加1笼5个的(也可能选出1笼3个的再加2笼4个的). 当然有时包子大叔无论如何也凑不出顾…
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5281 二分一个答案比值,因为最后要*1000,不如先把 v[] *1000,就可以二分整数: 枚举 mid ,如果 mid 小于等于 ans ,则 ∑v[i] - mid * ∑w[i] >= 0,可以继续往大调整,为了使答案最大,背包找一下使这个值最大的组合,看看能否 >=0: 数组开 1000 即可... 把 w 大于 1000 的直接当做最大的 w . 代码如下: #include…
http://www.cnblogs.com/ACMan/archive/2012/08/14/2637437.html #include <iostream> #include <string> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> #include <stack&g…
题目链接:https://vjudge.net/contest/103424#problem/E 题目大意: 给你一堆硬币,让你分成两堆,分别给A,B两个人,求两人得到的最小差. 解题思路: 求解两人分得钱币的最小差值,巧妙地转化为01背包问题. sum代表这堆钱币的总价值,ans=sum/2,求出得钱较少的人的钱币总量,即在这堆钱币中挑选出一定量的钱币,使得它的总值为小于或等于ans的最大值,即将它转化为01背包问题,背包容量为ans,每一个钱币看成价值与体积相等的物品. #include <…
https://vjudge.net/problem/UVA-12563 题意: 在一定的时间内连续唱歌,最后一首唱11分钟18秒的劲歌金曲,问最多能长多长时间. 思路: 0-1背包问题,背包容量为t-1,因为至少还要留1秒钟来放劲歌金曲.还需要注意的是题目要求的是在唱最多首歌的情况下所能唱的最长时间,所以这里我们来限制一下时间,对于j时刻,我们要求正好唱完这首歌,那么这样唱的歌肯定是最多的. #include<iostream> #include<algorithm> #incl…
这是一道不错的题.首先通过分析,贪心法不可取,可以转化为01背包问题.但是这过程中还要注意,本题中的01背包问题要求背包必须装满!这就需要在普通的01背包问题上改动两处,一个是初始化的问题:把dp[0]初始化为0,而其它的dp值都初始化为-1,表示不符要求.为什么这么初始化?背包九讲里说到:“初始化的dp数组事实上就是在没有任何物品可以放入背包时的合法状态.如果要求背包恰好装满,那么此时只有容量为0的背包可能被价值为0的nothing“恰好装满”,其它容量的背包均没有合法的解,属于未定义的状态,…
题目描述 在之前的上机中,零崎已经出过了01背包和完全背包,也介绍了使用-1初始化容量限定背包必须装满这种小技巧,接下来的背包问题相对有些难度,可以说是01背包和完全背包的进阶问题. 多重背包:物品可以有0-n件. 对于第i种物品,我们有取0件,1件…n [ i ] 件共n [ i ] +1种策略,状态转移方程为f [ i ] [ v ] = max { f [ i - 1 ] [ v - k × c [ i ] ] + k × w [ i ] | 0 <=k<= n [ i ] }.在这里,…
题目描述 Description 背包体积为V ,给出N个物品,每个物品占用体积为Vi,价值为Wi,每个物品要么至多取1件,要么至多取mi件(mi > 1) , 要么数量无限 , 在所装物品总体积不超过V的前提下所装物品的价值的和的最大值是多少? 输入描述 Input Description 第一行两个数N,V,下面N行每行三个数Vi,Wi,Mi表示每个物品的体积,价值与数量,Mi=1表示至多取一件,Mi>1表示至多取Mi件,Mi=-1表示数量无限 输出描述 Output Descriptio…
 FATE Problem Description 近期xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务.久而久之xhd開始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级.如今的问题是,xhd升掉最后一级还需n的经验值,xhd还留有m的忍耐度,每杀一个怪xhd会得到对应的经验,并减掉对应的忍耐度.当忍耐度降到0或者0下面时,xhd就不会玩这游戏. xhd还说了他最多仅仅杀s仅仅怪.请问他能升掉这最后一级吗?   Input 输入数据有多组,对于每组数据第…
Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 32309   Accepted: 10986 Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar.One day Tony opened his money-box and found there were some…
题目大意:有一个长度为$n(n\leqslant10^5,n=0\pmod2)$的字符串,字符集大小为$52$,有$q(q\leqslant10^5)$次询问,每次询问第$x,y$个字符在这个字符串的同一侧,并且所有相同字符在字符串的同一侧的方案数. 题解:因为字符集大小只有$52$,所以本质不同的询问只有$52\times52$种,预处理. 发现若确定了左右各放那几种字符后方案数是一定的,为$\dfrac{\left(\dfrac n2!\right)^2}{\prod\limits_{i=1…
Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6279    Accepted Submission(s): 2561 Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. One d…
题意 题目链接 Sol 多年以后,我终于把这题的暴力打出来了qwq 好感动啊.. 刚开始的时候想的是: 设\(f[i][j]\)表示第\(i\)轮, 第\(j\)个人血量的期望值 转移的时候若要淦这个人,那么\(f[i][j] = (f[i - 1][j] + 1) * p + (f[i - 1][j]) * (1 - p)\) 然后发现自己傻逼了..因为期望不能正着推. 考虑直接推概率,设\(t[k][i][j]\)表示第\(k\)轮,第\(i\)个人,血量为\(j\)的概率 这玩意儿是可以转…
一大波模板正在靠近 1.01背包 问题:有n件物品和一个容量为v的背包,第i件物品的费用(即体积)是w[i],价值是v[i],求解将哪些物品装入背包可使这些物品的费用和不超过背包容量,且价值总和最大. 动态转移方程为f[j]=max(f[j],f[j-w[i]]+v[i]),注意关于背包容量要倒着循环,来保证每个物品只选一次 //二维 ;i<=n;i++) ;j--) f[i][j]=max(f[i-][j],f[i-][j-w[i]]+v[i]); cout<<f[n][m]; //一…
有一点乱搞吧......对人对背包的理解有些考验,要想知道去掉某个点的值,可以选择对前缀求一次背包,后缀求一次背包,而且不省掉价钱那一维, 这样每个点就可以由前后组合成了,枚举一下价钱取max即可 直接01的多重背包就可以过 #include<bits/stdc++.h> using namespace std; ; int n,m,q,ans,v[maxn],w[maxn],c[maxn]; int f[maxn][maxn],g[maxn][maxn]; int main(){ scanf…
收录了最近本人完成的一部分codeforces习题,不定期更新 codeforces 1132E Knapsack 注意到如果只使用某一种物品,那么这八种物品可以达到的最小相同重量为\(840\) 故答案一定可以被写成\(840k+x(k,x\in N_+)\),我们将\(x\)称为"余下的部分" 故而设\(dp[i][j]\)为当前考虑了前\(i\)个物品,它们所占的余下的部分的重量为\(j\)时,最多可以组成多少个\(840\) 对于每个\(i\)预处理出枚举上界暴力转移即可 #i…
题意与分析 学习本题的时候遇到了一定的困难.看了题解才知道这是二重背包.本题的实质是二重完全背包.二维费用的背包问题是指:对于每件物品,具有两种不同的费用,选择这件物品必须同时付出这两种代价:对于每种代价都有一个可付出的最大值(背包容量).问怎样选择物品可以得到最大的价值.设第i件物品的两种代价分别为$a_i$和$b_j$,两种代价可付出的最大值(两种背包容量)分别为$V$和$U$,物品的价值为$w_i$,那么我们可以改进原来的状态转移方程,则定义$dp[i][j][k]$为选前i件物品,前两个…