LeeBlog

导航

随笔分类 -  DP

1 2 下一页

HDU 1059 Dividing 多重背包
摘要:这题想了想用母函数应该也可以做,不过得考虑一个细节,就是加起来的总和是否为奇数,我找了好久一直没找出错误,原来是没考虑奇数。。 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 阅读全文

posted @ 2011-05-20 10:27 LeeBlog 阅读(256) 评论(0) 推荐(0)

母函数用多重背包来解
摘要:其实母函数基本都可以用多重背包来解,我在做母函数时,我的代码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 阅读全文

posted @ 2011-05-18 17:07 LeeBlog 阅读(311) 评论(0) 推荐(0)

多重背包O(N*V)算法详解(使用单调队列)(转载)
摘要:多重背包问题:有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 – 阅读全文

posted @ 2011-05-18 14:26 LeeBlog 阅读(412) 评论(0) 推荐(0)

HDU 2844 Coins 多重背包
摘要:这题看着我第一感觉是母函数,但是据说母函数会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( 阅读全文

posted @ 2011-05-18 10:51 LeeBlog 阅读(192) 评论(0) 推荐(0)

HDU 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 多重背包
摘要:下面是以简短代码,但是我觉得还是标准版的好#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 阅读全文

posted @ 2011-05-18 01:39 LeeBlog 阅读(275) 评论(0) 推荐(0)

HDU 1085 Holding Bin-Laden Captive! 母函数||背包||递推
摘要:水题 。。 直接把所有可能枚举。。 最后找出没有可能的,即系数为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 阅读全文

posted @ 2011-05-12 10:37 LeeBlog 阅读(185) 评论(0) 推荐(0)

HDU 1398 Square Coins
摘要:好吧。。 这题是母函数的同一类型题。。。。。暴力也可以过#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 + 阅读全文

posted @ 2011-05-12 08:59 LeeBlog 阅读(159) 评论(0) 推荐(0)

HDU 2079 选课时间(题目已修改,注意读题) 母函数 || 多重背包
摘要:今天做这题才知道原来母函数的原型不是从第二个括号开始,那不过是优化而已,除了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 < 阅读全文

posted @ 2011-05-11 22:00 LeeBlog 阅读(623) 评论(1) 推荐(0)

HDU 2553 N皇后问题
摘要:这题跟其实是以DFS经典题,如果按一般思路一行一行来选,那样会灰常暴力,但是仔细思考可得这题可简化思路,因为没行只能放一个,所以只要搜索N个就行了。。。。。 而对于每一个只要判断跟前面是否有冲突就行了( DP 思想,分步来 )。#include<stdio.h>#include<string.h>int n,map[20],des[20],cnt,num[11];void DFS( int num ){ if( num == n + 1 ) { ++cnt; return ; } for( int i = 1; i <= n; ++i ) { if( !des[i 阅读全文

posted @ 2011-05-10 19:18 LeeBlog 阅读(236) 评论(0) 推荐(1)

HDU 2660 Accepted Necklace DFS || 多重背包
摘要:这题是以多重背包题..... 不过还不会多重... 只会简单的... 这里用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 阅读全文

posted @ 2011-05-08 09:58 LeeBlog 阅读(306) 评论(0) 推荐(0)

HDU 1465 不容易系列之一
摘要:一个错排公式直接解决 水过#include<stdio.h>long long num[25];void chart( ){ num[1] = 0; num[2] = 1; for( int i = 3; i < 25; ++i ) num[i] = ( num[i-1] + num[i-2] ) * ( i - 1 ); }int main( ){ chart( ); int n; while( scanf( "%d",&n ) != EOF ) printf( "%I64d\n",num[n] ); return 0;} 阅读全文

posted @ 2011-05-07 09:58 LeeBlog 阅读(284) 评论(0) 推荐(0)

HDU 2049 不容易系列之(4)——考新郎
摘要:#include<stdio.h>long long num[25],N[25];int main( ){ num[1] = 0; num[2] = 1; N[1] = 1; N[2] = 2; N[0] = 1; for( int i = 3; i < 25; ++i ) num[i] = ( num[i-1] + num[i-2] )*( i - 1 ),N[i] = i * N[i-1]; int t,n,m; scanf( "%d",&t ); while( t-- ) { scanf( "%d%d",&n,&a 阅读全文

posted @ 2011-05-06 22:40 LeeBlog 阅读(323) 评论(0) 推荐(0)

HDU 2048 神、上帝以及老天爷 典型错排 DP
摘要:这题我看了好几次,因为没学过错排,一直不敢做,今天看了下错排,可以用错排的公式做,但一神牛告诉我,可以DP,DP公式f( n ) = ( f( n - 1 ) + f( n -2 ) ) * ( n - 1 );#include<stdio.h>double num[25],N[25];void chart( ){ num[1] = 0; num[2] = 1; N[1] = 1; N[2] = 2; for( int i = 3; i < 25; ++i )//num[i]是错排 num[i] += ( num[i-1] + num[i-2] ) * ( i - 1 ),N 阅读全文

posted @ 2011-05-06 17:19 LeeBlog 阅读(564) 评论(0) 推荐(0)

HDU 1160 FatMouse's Speed 最长上升子序列 简单DP
摘要:这题开始看有点麻烦,因为又上升又下降的,但仔细想想,其实只要先处理一个变量,只剩下一个变量是不是就好处理了呢?对的?就跟最长子序列这是链接http://www.cnblogs.com/Lvsi/archive/2011/04/22/2025093.html.整体思路就是对重量排序,然后根据速度的的下降来找到最长的速度下降子序列.#include<stdio.h>#include<stdlib.h> int n,max;struct e{ int w,s,d,pri,flag;}v[1005];int cmp( const void *a,const void *b ){ 阅读全文

posted @ 2011-04-27 19:14 LeeBlog 阅读(276) 评论(0) 推荐(0)

HDU 1203 I NEED A OFFER! 简单DP
摘要:这题是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 阅读全文

posted @ 2011-04-27 16:00 LeeBlog 阅读(199) 评论(0) 推荐(0)

HDU 2602 Bone Collector 背包
摘要:这是一道经典的背包问题很水有两种方法,如果用二维做的话就要注意,体积要重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] & 阅读全文

posted @ 2011-04-27 11:16 LeeBlog 阅读(301) 评论(0) 推荐(0)

HDU 1257 最少拦截系统 DP
摘要:这题是一DP题,开始我听小白的直接暴力,结果测试数据能过,但提交就wa,我哭啊,呜~~~~,我重敲了一次,结果还是悲剧,几个小时啊,我就在这悲剧,最后翻出小晨的代码,发现好简单的,百度上说是最长上升子序列,于是直接1A了,最长上升子序列就是在一个数列a1-an中,从中选取几个数,这个数组成的序列递增,并且是a1到an中这样子序列中最长那一个。这个题其实也符合最长上升子序列,只要后面有一个比前面高的,就要加一个拦截系统(要增加一个拦截系统,首先要知道前面已经有多少涛拦截系统)。//这个能A#include<stdio.h>int n,dis[100000],max,dp[100000 阅读全文

posted @ 2011-04-25 16:13 LeeBlog 阅读(375) 评论(2) 推荐(0)

HDU 2571 命运
摘要:这题很DP就是跟前面一样一步一步来,先找到一部分,然后把这部分扩大,最后至全部,最终找出全局最优解,这里要注意,他给的测试数据太淫荡了,其实|K|>100,所以max初始化时给个1111吧#include<stdio.h>#include<string.h>int n,num[25][1024],m;int main( ){ int t; scanf( "%d",&t ); while( t-- ) { scanf( "%d%d",&n,&m ); memset( num,0,sizeof( num 阅读全文

posted @ 2011-04-23 22:44 LeeBlog 阅读(192) 评论(0) 推荐(0)

DP 动态规划小结
摘要:到今天为止,动态规划入门已经有好几天题也做了几个了,其实这部分题大概都是一个规律:要找到整个问题的最优解,先找到局部的最优解,然后将范围逐渐扩大,最后扩大到全局就可以了,例如HDU 1087 super jumping!先从第一个起,先把第一个的最优解找到,然后往后增加,找到第一个到第二个的最优解,并保存在数组2中然后再增加,找到第一个到第三个的最优解,保存在第3个数组中,然后一直往后推移,一直找到全部的最优解。这其中就存在一个问题,为什么要从前面一个一个找呢?为什么不一次找完呢?那样多省时间?我想说:会用我不用啊!傻啊!你!。有狠不把前面n-1个的最优解找出来,直接找到第一个到第n个的最优解 阅读全文

posted @ 2011-04-22 23:22 LeeBlog 阅读(179) 评论(0) 推荐(0)

HDU 1003 Max Sum
摘要:本题跟最大子序列差不多,是姊妹题,其实解决了上个,这个只要解决几个地方就可以了,请注意如果有全部是负数,就把这些负数中最大的输出来。#include<stdio.h>#include<string.h>int t,n,pos,num[110000],add[110024],pri[110024];void cal( ){ int pos = 1; for( int i = 1; i <= n; ++i ) { if( add[i-1] >= 0 && (add[i-1] + num[i] >= 0) )//here { add[i] = 阅读全文

posted @ 2011-04-22 20:38 LeeBlog 阅读(169) 评论(0) 推荐(0)

1 2 下一页