03 2012 档案
摘要:该题要用分组背包做,这里就是要怎样处理0必须选,1最多选一个,2任意选的问题;这里我们就开个二维数组;f[i][j],i表示第组,j表示时间;当该组为0时,我们在该组的选择可以来自上一组的结果,也可以来自该组的结果;如果为1那么结果只能依赖上一组的结果,如果依赖本组那么就会造成该组会多选;为2是那就是一个01背包;View Code #include<cstdio>#include<iostream>#include<cstring>using namespace std;class node{public: int cost,happy;};class N
阅读全文
摘要:该题是一道分组背包题;题意就是ACboy发最多M的时间能够得到最多效益;输入有N没课程,没门课程发费j天得到的效益是map[i][j];View Code #include<iostream>#include<cstdio>#include<cstring>using namespace std;int map[124][124];inline int Max( int a , int b ){ return a > b ? a : b; }int DP( int N , int M ){ int f[124][124] ={ 0 }; for( in
阅读全文
摘要:该题就用反方向思考,就是p = 1.0 -p 就可以了,不安全系数变成安全系数,再把安全系数相乘就可以了;View Code #include<iostream>#include<cstdio>#include<cstring>using namespace std;int ZeroOnepack( double pro[] ,int value[],double p ,int N, int sum ){ double f[10024] ={ 1.0 }; for( int i = 0 ; i < N; i++ ) { for( int j = sum
阅读全文
摘要:这是我A的第一个分组背包,这就没有用优化,这是暴力的,这里优化可以先对分组进行排序,那样就会节约好多的时间;分组背包是:有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。这里我们就可以设计成一个二维数组,f[kind][money],(kind表示当前已经拥有的品牌种类数目,money 表示当前已经花费了的前的数目)。当前状态的来源有二:A、当前品牌数目的前提之下取最大的值;B、在比当前品牌数目少的基础之上放一个另外品牌的商品的最大值;
阅读全文
摘要:一道简单的动态规划题,与http://acm.hdu.edu.cn/showproblem.php?pid=2084数塔思想是一样的,都是从后面往前面推;View Code #include<iostream>#include<cstdio>#include<cstring>using namespace std;int map[100024][12];int sum[100024][12];inline int Max( int a , int b ){ return a > b ?a : b;}int main( ){ int n,place, T
阅读全文
摘要:这个题我们可以直接顺序往下面暴力,每次选取最大的;View Code #include<iostream>#include<cstring>#include<cstdio>using namespace std;int main( ){ int Case ,n ,m; int map[24][1024],sum[24][1024]; while( scanf( "%d", &Case )==1 ) { while( Case -- ) { memset( map , 0 ,sizeof( map ) );// memse...
阅读全文
摘要:View Code #include<iostream>#include<cstdio>#include<cstring>#include<vector>using namespace std;vector<int>list[124];int value[124],num[124];int dp[124][124];int hash[124];void DFS( int f ,int M ){ int len = list[f].size(); int t=0; t = (num[f]+19)/20; for( int i = t ;
阅读全文
摘要:链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561这题是一道树形DP(依赖背包);这是我学树形DP的做的第一题,这种背包问题的物品间存在某种“依赖”的关系。也就是说,i依赖于j,表示若选物品i,则必须选物品j。为了简化起见,我们先设没有某个物品既依赖于别的物品,又被别的物品所依赖;另外,没有某件物品同时依赖多件物品。对于这种背包我们可以建立成一棵树,父节点就是子节点所要依赖的;根据题意知道我们选择如果要打该节点,那么必要打掉该父节点;如果打父节点,总共还剩N次可以打的机会,那么我们可以对于子节点是打还是不打,打得时候可以分给该节点几次,我们就从这
阅读全文
摘要:题意:给你一段内存单元,你可以对它进行一下操作:开辟一个内存块,如果开辟成功返回该内存块最左边的值;删除包含X的内存段元,如果成功输出该内存块的左右值;找到第X快内存块,如果成功输出该内存块的最左边的值;清除内存;这个题的思想与http://poj.org/problem?id=3667是一样的;这题还要做一个处理的是建立一个链表把之前的内存块首尾点给存储起来,这样就容易对它进行操作;其余的地方与Hotel一样,这里就不累叙了;View Code #include<iostream>#include<cstdio>#include<cstring>#incl
阅读全文
摘要:这是一道多重背包的题目;题意:有N那种物件,每种物件有个重量与个数;求A要般的重量不比B的轻,但要使他们的重量只差最小;#include<iostream>#include<cstdio>#include<cstring>using namespace std;void Completepack( int value, int sum ,int f[] ){ for( int i = value ; i<= sum ; i++ ) if( f[i] < f[i-value] + value ) f[i] = f[i-value] + value;
阅读全文
摘要:题意:给出一个长度为N(N <= 100000)的数列,然后是两种操作:U A B: 将第A个数替换为B (下标从零开始)Q A B: 输出区间[A, B]的最长连续递增子序列;这里注意:操作数可为100000;如果单纯的用暴力的方法可定超时,这里只是区间的操作,那么我们可以用线段数来做;我们知道在一个区间如果左区间的右值比右区间的左值小,那么这两个区间可以合并成一个区间,在与左区间的最大值和右区间的最大值做比较,找出最大值;如果小于那么我们就直接可以把左区间的最大值和右区间的最大值做比较,找出最大值;这里就要设立几个变量:l_value 区间的最大连续递增序列的左值;r_value区间
阅读全文
摘要:题意:在一个8×8的棋盘中,给定你4个棋子A,再给你4个棋子B,问你在8步之内能不能够从A位置移动到B位置;规则:棋子能能上下左右移动,同时能跳过相邻的棋子到达相邻棋子的空地方;这个题要用双向搜索;同时我用一个8维的数组hash来构造一个图;当hash标记为1时表示A到过该点,标记为2时表示B到过该点;这里要注意就是A,B同时搜索时他们分别最多只能走4步,如果多于4步,那么他们步数之和就可能大于8;这里还要用到排序,这个很重要,因为4个点是不分形状大小的,那么我们就不会重复走;View Code #include<iostream>#include<queue>
阅读全文
摘要:这是一个双向搜索题,我用BFS把所有的点都搜索到;再进行两次搜索的比较;#include<cstdio>#include<cstring>#include<iostream>using namespace std;class Node{public: int x , y ; int step; int num; };Node queue[80024];int step[2][204][204],N,M;int d[4][2] = { 0,1,1,0,-1,0,0,-1 };char map[204][204];int BFS( int x1,int y1,
阅读全文
摘要:这题是记忆化搜索:#include<iostream>#include<cstdio>#include<cstring>using namespace std;int map[124][124];int ans[124][124];int N,M;int DFS( int x ,int y ){ int sum = 0; if( x == N && y == M ) return 1; if( ans[x][y]>=0 ) return ans[x][y]; for( int i=0; i<= map[x][y] ; i++ )
阅读全文
摘要:刚开始用暴搜一直RE了,后来加了一个标记就是把字符串转化成数字,如果出现过就标记它;有一组测试数据就是1111与5555是16;#include<iostream>#include<cstdio>#include<cstring>using namespace std;class Node{public: int step; char c[6]; Node() { memset( c , 0, sizeof( c ) ); } };char num1[6],num2[6];Node queue[10024];bool hash[10000];bool pus
阅读全文
摘要:简单的搜索题:#include<iostream>#include<cstdio>#include<cstring>using namespace std;int flag,Count,step;char map[15][15];int STEP[15][15];bool hash[15][15];void DFS( int x, int y, int cnt ){ if( hash[x][y] ) {// flag =2; Count = cnt - STEP[x][y]; step = STEP[x][y...
阅读全文

浙公网安备 33010602011771号