摘要:这题想了想用母函数应该也可以做,不过得考虑一个细节,就是加起来的总和是否为奇数,我找了好久一直没找出错误,原来是没考虑奇数。。 fuck 这种问题我怎么能不考虑奇数呢。。。。。 啊 啊 啊啊 啊啊啊 啊啊啊啊 啊 啊啊啊啊好吧。。 上代码。。 二进制优化。。。 如果能拼出他们总和的平均值。那么在他们的平均值背包里能装下平均值。。#include<stdio.h>#include<string.h>int num[7],dp[200005],ave;inline int max( int a,int b ){ return a > b ? a : b; }void
阅读全文
摘要:其实母函数基本都可以用多重背包来解,我在做母函数时,我的代码500多MS有的甚至过不了,而cadl神的是0MS,就倍感惊讶啊,我的超时,为神马别人的那么少啊,一问原来是用背包做的,这里来讲一讲母函数用背包做的一点小理解吧,以HDU 1284为例,dp[j]代表着钱为j时的选法,当循环到第i次时,(即前面的coin[1,2....i-1]已经选完了 )对于j有两种选法,一:不选coin[i],那么它的选法就是原来不选coin[i]的选法dp[j],选coin[i]的选法有多少种呢???? 不就是dp[j-coin[i]] ( 为神马是这样呢?因为你如果在j那里选了coin[i],那么他选coin
阅读全文
摘要:多重背包问题:有N种物品和容量为V的背包,若第i种物品,容量为v[i],价值为w[i],共有n[i]件。怎样装才能使背包内的物品总价值最大?网上关于“多重背包”的资料倒是不少,但是关于怎么实现O(N*V)算法的资料,真得好少呀,关于“单调队列”那部分算法,又没说明得很清楚,看了几遍没看懂原理,只好自己动脑去想怎么实现O(N*V)算法。若用F[i][j]表示对容量为j的背包,处理完前i种物品后,背包内物品可达到的最大总价值,并记m[i] = min(n[i], j / v[i])。放入背包的第i种物品的数目可以是:0、1、2……,可得:F[i][j] = max { F[i - 1] [j –
阅读全文
摘要:这题看着我第一感觉是母函数,但是据说母函数会TLE,就果断多重背包了,而这里用多重背包做,明显不能直接把dp[n]输出来,那样结果是错的,那怎么才能找到种类呢。if( dp[i] ) ++c;??????这样行吗???? 不行,这是后要想到dp[i]的含义,dp[i]代表着在重量i时能找到的最大价值,而这里的重量和价值都是钱,所以就有很方便的一个地方了,dp[i]中最多能装下i的话那么肯定i能够选到,所以就有判断条件了if( dp[i] == i ) ++c;直接上代码吧#include<stdio.h>#include<string.h>//#define max(
阅读全文
摘要:下面是以简短代码,但是我觉得还是标准版的好#include<stdio.h>#include<string.h>int n,m,v[105],w[105],num[105],dp[105],ma;int max( int a,int b ){ return a > b ? a : b;}int main( ){ int t; scanf( "%d",&t ); while( t-- ) { ma = 0; memset( dp,0,sizeof( dp ) ); scanf( "%d%d",&n,&m
阅读全文
摘要:这题是我第一次写多重背包,1RE,1WA,#include<stdio.h>#include<string.h>int n,v[55],num[55],dp[250000],sum,all;int max( int a,int b ){ return a > b ? a : b;}int main( ){ while( scanf( "%d",&n ),n > 0 ) { sum = 0; for( int i = 0; i < n; ++i ) scanf( "%d%d",&v[i],&
阅读全文
摘要:这题题意大致是一个蓄钱小猪,空质量w1,装了钱的质量w2,然后给出各种钱的价值及重量,问着个钱罐至少要存多少钱这题是完全背包入门的一经典啊,现在我还不是太理解完全背包。下面说说我的理解吧。完全背包是要把每种都尽量往里面放,每种都放到使总值最大,(为神马这样放就能把每种放到最大呢?客观请继续看)最后看所有种类全部放进去,并且放到使总值最大,好吧。至于为神马从后面往前面放就是0-1背包呢,即只能放一个,并且是依靠前面的呢,因为如果从w[i]-W,在0-1背包中,当W-w[i]>w[i]时,就有可能在dp[W]放w[i]时就已经把w[i]放进去了,即完全背包,这样就重复放了w[i],这显然与0
阅读全文
摘要:这题开始我拿了,不知怎么下手,但幸好这题是在背包这里,提示了我,肯定能用背包解,但显然概率不能作为一维数组的下标,所以只能找价值来当一维数组下标,而要不失败,即全部成功,求全部成功的概率就行了。其实仔细想想0-1背包的二维中两个下标是对称的。还有0要初始化为1,因为如果神马都不抢成功率为1#include<stdio.h>#include<string.h>double dp[10005],W,w[10005];int n,v[10005],ma;double max( double a,double b ){ return a > b ? a : b;}void
阅读全文
摘要:水题 。。 直接把所有可能枚举。。 最后找出没有可能的,即系数为0 的最小数#include<stdio.h>#include<string.h>int s[4] = {0,1,2,5},m1[100000],m2[100000],num[4],max;void gf( ){ memset( m1,0,sizeof( m1 ) ); memset( m2,0,sizeof( m1 ) ); for( int i = 0; i <= num[1]; ++i ) m1[i] = 1; for( int i = 2; i <= 3; ++i ) { for( in
阅读全文
摘要:好吧。。 这题是母函数的同一类型题。。。。。暴力也可以过#include<stdio.h>int sq[18],m1[305],m2[305];void chart( ){ for( int i = 0; i < 305; ++i ) m1[i] = m2[i] = 0; for( int i = 0; i < 18; ++i ) sq[i] = i * i; m1[ 0 ] = 1; for( int i = 1; i <= 17; ++i ) { for( int j = 0; j <= 300; ++j ) for( int k = 0; ( j +
阅读全文
摘要:今天做这题才知道原来母函数的原型不是从第二个括号开始,那不过是优化而已,除了1^n,2^n那种类型可以从2开始外其他都要从1开始。好了,上代码吧。#include<stdio.h>int n,k,m1[450],m2[450],t,a,b;int num[15],sc[15];void gf( ){ for( int i = 0; i <= num[1];i++ ) m1[i*sc[1]] = 1; for( int i = 2; i <= k;++i ) { for( int j = 0; j <= n; ++j ) for( int l = 0; l <
阅读全文
摘要:这题是以多重背包题..... 不过还不会多重... 只会简单的... 这里用DFS做就行了..... 不过这里如果不把当前位置传下去就会超时的噢... 我开始一直TLE 后来把当前状态传下去就A了15MS#include<stdio.h>int V[25],W[25];int des[25],n,k,we,max,dp[25][25];int inf = 0x7fffffff;void DFS( int p,int num,int val,int wei )//p不可少,否则超时.... 悲剧额....{//以后做这种深搜的一定先考虑要不要传递当前状态.. 以此来减少深搜时间 if
阅读全文
摘要:这题是Bone collector 是以姊妹题,同样的背包http://www.cnblogs.com/Lvsi/archive/2011/04/27/2030158.html不过比较大小的条件要换一下,至少有一个被选上的概率为1-( 1-dp[j-w[i]] ) * ( 1 - v[i] ),这个地方用到了高中的概率,很简单的仔细想想就过了.不多说了,来看代码把#include<stdio.h>#include<string.h>int n,m,w[10005];double v[10005],dp[10005];void DP( ){ memset( dp,0,si
阅读全文
摘要:这是一道经典的背包问题很水有两种方法,如果用二维做的话就要注意,体积要重0开始,因为测试数据很淫荡#include<stdio.h>#include<string.h>int n,V,t,val[1024],v[1024],dp[1024][1024];void DP( ){ memset( dp,0,sizeof( dp ) ); for( int i = 1; i <= n; ++i ) for( int j = 0; j <= V; ++j ) if( j >= v[i] && dp[i-1][j-v[i]] + val[i] &
阅读全文
摘要:i相信知道做前面那个后这个应该很水了#include<stdio.h>int m1[40000],m2[40000];void chart( ){ for( int i = 0 ; i <=32780; ++i ) { m1[i] = 1; m2[i] = 0; } for( int i = 2; i <= 3;++i ) { for( int j = 0; j <= 32780; ++j ) for( int k = 0; k + j <= 32780; k += i ) m2[j + k] += m1[j]; for( int j = 0; j <
阅读全文