08 2012 档案
摘要:题意:从一条线段(property)上观察另一与之平行的线段(house),其中有很多与它们都平行的线段(障碍物),求在property得可见整条线段house的最长连续范围的长度。类别:直线交思路:求出线段house对于每条障碍物在线段property在的最大投影,投影即为在线段property上,被这条障碍物遮蔽,而无法看见整条线段house的范围。然后求出线段property上没有被投影到的最长的连续区间长度即为所求答案。另外,要注意先排除掉位置不是在house和property之间的障碍物。View Code #include<stdio.h>#include<str
阅读全文
摘要:还不错的一道题目,要注意看清题意。注意:1. 普通行驶的情况下,每通过1段赛道,可以获得20%的能量(N2O). 所以加速情况不加能量2. 能量集满后获得一个加速卡(同时能量清0). 加速卡最多可以储存2个,也就是说当你有2个加速卡而能量再次集满,那么能量清零但得不到加速卡。看清题目的话, 这题状态转移推一下,不是很难。View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define inf 1<<29int n, l;int d
阅读全文
摘要:第一次遇到20s的题,果断暴力,贡献多个TLE, 水题也不是完全水的,必须要适当的优化一下,学习了。View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define lld __int64lld gcd(lld a, lld b) //最大公约数 { return a ? gcd(b%a, a) : b; }int n, k;int a[802];bool vis[802];int main(){ int i, j; while( ~scan
阅读全文
摘要:题意:给出一个长度为N(N <= 100000)的数列,然后是两种操作:U A B: 将第A个数替换为B (下标从零开始)Q A B: 输出区间[A, B]的最长连续递增子序列询问的次数m <= 100000。类型:区间合并这题跟POJ hotel差不多,这题应该比hotel简单一些,因为 update是单点更新,所以每次更新数据都是更新到低的,所以不用写pushdown函数,pushup里面比hotel多了一个判断,即num[m] < num[m]时左右儿子的数据才能合并,否则不合并,其它跟hotel无差。View Code #include<stdio.h>#
阅读全文
摘要:#include<set>#include<map>#include<string>#include<vector>#include<iostream>#include<algorithm>using namespace std;int main(){ vector<int> V; /*for(int i=10;i>=0;i--) { V.push_back(i); V.push_back(i); } int size=V.size(); for(int i=0;i<size;i++) { prin
阅读全文
摘要:代码风格:notonlysuccess。单点更新:最最基础的线段树,只更新叶子节点,然后把信息用PushUP(int r)这个函数更新上来。很基础的,notonlysuccess里面有的, 先学学它里面的吧。网站: http://www.notonlysuccess.com/index.php/segment-tree-complete/以下是notonlysuccess里没有的1. POJ 2828 Buy Tickets题意:插队问题.关键:如何将这些人插入队伍中去。类型:单点更新思路:人要逆着插入队伍, 最先插入的一个数据的位置明显是题目给定的位置,可以确定,然后插入的几个人的位置前面插
阅读全文
摘要:转载请注明出处:優YoU http://user.qzone.qq.com/289065406/blog/1309142308大致题意:按照顺时针或逆时针方向输入一个n边形的顶点坐标集,先判断这个n边形是否为凸包。再给定一个圆形(圆心坐标和半径),判断这个圆是否完全在n变形内部。解题思路:题意已经很直白了。。就是那个思路。。。注意输入完顶点集后,要封闭多边形,方便后面枚举边。封闭方法:定义点集数组Vectex[1~n]记录n个顶点,再令Vectex[0]=Vectex[n],Vectex[n+1]=Vectex[1]1、判断凸包:由于点集已经按某个时针方向有序,因此可以先定义一个方向系数dir
阅读全文
摘要:题意:给你一些图形,输入点,判断各个图形的相交情况。分析: 输入输出比较麻烦,其它很水。注意点:1. 是正方形的话给你两个点是对角线的两端点,会求另外两点的坐标。已知 (x1, y1),(x3, y3) 求(x2, y2),(x4, y4);可以由方程组:x1 + x3 = x2 + x4;x1 - x3 = y2- y4 ;y1 + y3= y2 + y4;y3 - y1 = x2 - x4 ;解方程一下即可。2.多边形和矩形都是按顺序输入点的,也就是说按连边的顺序输入。3.输出的时候,如果相交要考虑多种情况。注意这里的输出:跟 1 个相交 with B跟 2 个相交 with B and
阅读全文
摘要:昨天晚上开始想这题,一拿到题目,数据才30,果断想到枚举,而且有一点可以肯定:光线必然贴着其中的2个顶点,不贴顶点根本无法做;刚开始想得超复杂,枚举任意2个点组成的直线,然后跟所有边界线判断是否相交等等情况, 由于边想别敲,结果才我写得发现有漏洞,而且很难用语言改正,所以放弃了,不久就郁闷地睡觉去了,想想有没有好的方法。第二天起来,还是想这个问题,诶,想想有什么新方法。真心想不出来, 结果无聊去看了看汝的黑书,发现这题在黑书P359,我也是把前面的计算几何看完了才看到的。结果刚学了上一个模板就来做这题,先看了看黑书上的思路,诶,我快速打了一遍,直线和线段相交求交点 被我打成 两线段相交求交点,
阅读全文
摘要:题目还行,可惜自己不争气。一开始就想到了所有情况:1. 两条线不相交,不能装水。2. 两条线重合 或 平行 不能装水。3. 其中一条线水平放置,不能装水。4. 如下图, 不能装水,同理两直线都向右斜时,也有这种情况4. 把3中的图稍微改动一下,就能装水了,如下图可见,先判断是不是1,2,3 这几种情况,如果不是,那么4,5这两种情况要再判断一下。我想,这次不能再看别人的解题报告, 要自己做才能学到许多,尽管自己的方法不是很好,以下思路纯自己构思,代码纯手写, 写得太乱, 太杂, 尽管做了一下午,每次都是测试了好几组数据才交, 还是16WA,但完全靠自己A了心情就是不一样,爽啊。通过这题我学会了
阅读全文
摘要:有了向量 我们就可以选取一个最外侧的点了利用向量 我们可以比较哪个点"更外侧"比如点K和点I 我们利用向量JK乘以向量JI得到一个数 这个数应该是负数 说明I比K更外侧两个向量的比较具有传递性所以我们可以像N个数里取最大的数一样取出最外侧的遍历所有点 每个点都和现有最外侧的点比较 得到新的最外侧的点至此两个问题都得以解决 我们可以写出满足一般要求的卷包裹算法了两个问题如下:1.怎么确定一个肯定在凸包上的点?这个问题很好解决 取一个最左边的也就是横坐标最小的点如果有多个这样的点 就取这些点里 纵坐标最小的这样可以很好的处理共线的情况2.如何确定下一个点(即最外侧的点)?我们需
阅读全文
摘要:无论点怎么分布,总有一条路径能使ant经过所有的点。方法1:第一次选坐标y值最小的坐标为起始点 也是当前停留点,然后 以当前点为参照,对之后的几个点按级角(斜率)从小到大排序,取极角最小的点,然后继续重复操作,直到所有点取完为止。View Code #include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>using namespace std;#define inf 1<<29struct point{ int num, x, y;}p[33];poi
阅读全文
摘要:诶,题目太坑爹。注意点:1. 给出的矩形的两个点是随意的,可能是左上,右下 或 左下,右上。2. 如果线段在矩形里面算相交;3. 判断线段相交的模版必须完善 (考虑所有情况):共线,规范相交,非规范相交。View Code #include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>using namespace std;#define eps 10e-8struct point{ double x, y; point(){} point(double xx, dou
阅读全文
摘要:本题关键:如何找到最少的路径。刚刚做的一题计算几何时建图的,做到这道题,第一个想法就是建图,找最短路, 后来细想操作太多太繁琐,不好做, 所以放弃了,觉得应该有简单的做法。 思考很关键:从外围四个墙的某一个门进来,走到宝藏,最小走几个门,实际就是进门点和宝藏的连线goalLine穿过几个点。证明不好证,但如果说明大体的思想其实挺简单的:思想有点像两点之间直线最短。不要去管纵横交错的小线段,只管一开始原始输入的线段,因为在正方形范围内,这些线段可以想象为无限长,进门的点和宝藏点中间横跨着k条直线(墙 ),你就无法绕过它们,只能穿过它们 ,你往左往右走都只会徒增加你要穿过的墙,就这最基本的k道墙你
阅读全文
摘要:有技巧的暴力过了View Code #include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>using namespace std;#define eps 10e-8#define inf 1<<29struct point{ double x, y;};struct seg{ point a, b;}s[100002];bool vis[100003];int ans[100003];int n;double cross(point p0, poin
阅读全文
摘要:构建模型非常重要。建图:把起点,终点,每个墙上的4个点分别看成图的顶点;把这些点中各对点连起来,如果与墙相交(判断两线段相交)则不连,然后floyd暴力一下。思路想到了就蛮清晰的,但我刚学计算几何,一直很纠结点写成结构体还是分开来写,调用的时候哪个比较方便,总觉得2个都很麻烦,诶,所以荒废了比较多的时间,以后不能这么2了。然后我把2种都写了一遍,写计算几何一定要注意规范。代码1:(函数调入点用double)View Code #include<stdio.h>#include<string.h>#include<math.h>#include<algo
阅读全文
摘要:题目大意:给出四个点确定两条直线。如果是一条线输出“LINE”,如果平行输出“NONE”, 如果有交点输出交点坐标。思路:注意是直线,不是线段啊。用两点式推出两条直线方程 :(y1 - y2)x + (x2 - x1)y = x2y1 - x1y2;(y3 - y4)x + (x4 - x3)y = x4y3 - x3y4;a1x + b1y + c1 = 0;a2x + b2y + c2 = 0;D = a1b2 - a2b1; D1 = b1c2 - b2c1; D2 = c1a2 - c2a1;D != 0时, x = D1 / D, y = D2 / D; 得到交点坐标。D = 0时;
阅读全文
摘要:若存在这样一条直线,过投影相交区域作直线的垂线,该垂线必定与每条线段相交,问题转化为问是否存在一条线和所有线段相交;若存在一条直线与所有线段相机相交,将该线旋转,平移,直到不能再动为止,此时该直线必定经过这些线段的某两个端点;所以枚举任意两个端点即可。需要注意的是,当枚举的两个端点很近的时候,即sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))<eps时,那么这两个点是可以认为重合的,由于如果把这两点的连线作为向量,向量的模会很小,就可能导致无论怎么做叉积结果都为0从而认为各个点都是和这两个点共线的。因此,在枚举两个端点的时候要避免这种情况,同时,避免枚举这种情况
阅读全文
摘要:在poj 2318的基础上 加上一个排序(因为板的坐标不是有序的),再加多一个统计就好了。View Code #include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>using namespace std;struct point{ int x, y;};struct node{ int up, down;}date[1007];int n, m;point toy[1007];point a, b;int ans[1007], cnt[1007];int cro
阅读全文
摘要:第一题计算几何,1A,好开心哦。View Code #include<stdio.h>#include<string.h>#include<math.h>struct point{ int x, y;};int up[5007],down[5007];;int n, m;point toy[5007];point a, b;int ans[5007];int cross(point o, point a, point b){ return ((a.x-o.x)*(b.y-o.y)-(a.y-o.y)*(b.x-o.x));}int find(point ke
阅读全文
摘要:计算几何题的特点与做题要领:1.大部分不会很难,少部分题目思路很巧妙2.做计算几何题目,模板很重要,模板必须高度可靠。3.要注意代码的组织,因为计算几何的题目很容易上两百行代码,里面大部分是模板。如果代码一片混乱,那么会严重影响做题正确率。4.注意精度控制。5.能用整数的地方尽量用整数,要想到扩大数据的方法(扩大一倍,或扩大sqrt2)。因为整数不用考虑浮点误差,而且运算比浮点快。一。点,线,面,形基本关系,点积叉积的理解POJ 2318 TOYS(推荐)http://acm.pku.edu.cn/JudgeOnline/problem?id=2318POJ 2398 Toy Storage(
阅读全文
摘要:给n个物品,容量为m的包,要求这样的方案数:选中n个物品放入背包后,剩下的物品中,任意一个都放不进去。我们先将物品按容量从大到小排序。考虑以下2种情况:1. 考虑一种特殊情况,一个都放不进去,就是剩下物品中体积最小的那个(体积为w[1])都放不进去,这个情况就会无解,答案为0;2. 一般情况:从小到大枚举不放入背包的体积最小的,那么此时比它小的物品都应该放入背包中,此时背包装载容量应为[m-w[u]+1,m] (1<=u<=n)我们可以对剩下的u+1到n的物品做01背包,然后将可行的方案统计出来,这样,第u件物品考虑了u-1次,总复杂度为O(n^2*m);优化:n较大的话会超时,我
阅读全文
摘要:题意:某电台要广播一场比赛,该电台网络是由n个网点组成的一棵树,其中m个点为客户端,其余点为转发站。客户端i愿支付的钱为p[i],每一条边需要的花费固定,问电台在保证不亏损的情况下,最多能使多少个客户端接收到信息?广播台所在的节点编号为1分析:树形DP1.用dp[u][j]表示从转发站u开始计算,满足其子树中j个顾客的最大收益 分析节点u的孩子节点v a.放弃该孩子v,值不变 b.取该孩子的若干的节点:dp[u][j-k]+dp[u][k]-cost[i][j](cost[i][j]为连通该边所需要付出的代价。)所以状态转移方程为:dp[u][j]=max(dp[u][j],dp[u][j-k
阅读全文
摘要:比较综合的题目。题意:有n个物品,有两辆车载重分别是c1,c2.问需要多少趟(c1,c2一起运一次就算1趟)能把物品运完。n比较小,只有10,而且需要把所有物品全部运完,便想到状态压缩来保存状态。首先记录好所有的可行状态,对于状态state能一趟运完。然后再利用01背包,dp[j],表示已运的状态为j,如果状态j与state[i]不冲突,则可以从状态j运一趟变为j|state[i]。View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int n
阅读全文
摘要:中文题,题意自己看树形DP将0设为根节点,总攻击数为m,背包容量应该是m+1(0点也看做城堡);基础的树形DP,自己推一下状态转移方程吧。View Code #include<stdio.h>#include<string.h>#include<vector>#include<algorithm>using namespace std;vector<int>edge[224];int dp[224][224];int p[224],m, n;void dfs(int u){ int i, j, k; dp[u][1]=p[u];//初
阅读全文
摘要:题意:一棵树,有n个结点,每个结点有w[i]个bug,有p[i]的brain。我从1号结点开始走,带着m个战士。1个战士可以消灭20个bugs如果我把某个结点的所有bug都消灭了我就能得到那个结点的brain。如果想攻击当前结点,那么必须先攻击了它的父结点(1号点除外)。注意:1. 其中当你攻占了当前结点,你可以分派人手,走向几个不同的子结点,去攻占更多。也就是说,不是单一的路径。2. 如果输入0个战士直接输出0,即使该洞bug数为0,要获得该洞brain值,也需要至少一人经过该洞穴(可以不停留),而用dfs计算会出现正值。本题数据小,节点100,如果数据大了尽量不要用vector,可能会超时
阅读全文
摘要:题意:给定一个面值Price, 1美分的硬币有c[1]个, 5美分的硬币有c[2]个,10美分的硬币有c[3]个,25美分的硬币有c[4]个,求用给定的硬币兑换Price面额的钱,并且要求硬币数最多,求出每种硬币得用多少个.题目关键:要保存路径,然后输出。我们用pre[j]表示最新更新j的那个状态,j-w[i]等状态,因为多重背包里有二进制压缩,有些状态转移1次纸币数量不一定只加了1,所以用num[j]表示状态转移到j加了多少张纸币。路径输出处理:memset(ans,0,sizeof(ans));for(i=m;i!=0;i=pre[i]) //用pre[j]把路径逆着走一边{ in...
阅读全文
摘要:题意:有钱sum,给出n组选择,每种选择有m个物品w,要买物品先必须买盒子,物品价格为w[i],价值p[i]。然后给出每种选择的一些物品的价格还有价值求取得最大值。物品依赖于盒子。按照背包九讲的做法:先对每组选择里的所有物品进行0-1背包处理,但背包容量为(总容量-盒子容量);然后跟上一组的状态比较来决定这一组选择 是选还是不选,取其中的较大值。用dp[i][j]表示第i组背包容量为j时的最大价值。在转移状态之前当前组选择的初始化:for(j=0;j<q;j++)//q表示盒子的价格 dp[i][j]=-INF;//当钱<盒子价格时,无价值,注意不要赋值为0, 这题有 重量为0,但
阅读全文
摘要:题意:给你钱的价值和数量,求能在价值m以内能够拼出多少种钱数。View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;bool dp[120003];int w[101],c[101];int main(){ int n, m, i, j; while(~scanf("%d%d",&n,&m)) { if(!m&&!n)break; for(i=1;i<=n;i++) scanf("
阅读全文
摘要:题意:说有一个人去买m元的东西,有n种钱币,没种钱币的面额是w[i],个数是C[i],售货员每种钱币有无数多个。现在这个人想让交易的钱个数最少,即找回的和付出钱的张数,最少。多重背包+完全背包。买家:多重背包;售货员:完全背包;开两个数组,分别计算出买家,售货员每个面额的最少张数。最重要的是上界的处理。可以注意到,上界为maxw*maxw+m(maxw最大面额的纸币),也就是24400元。(网上的证明)证明如下:如果买家的付款数大于了maxw*maxw+m,即付硬币的数目大于了maxw,根据鸽笼原理,至少有两个的和对maxw取模的值相等,也就是说,这部分硬币能够用更少的maxw来代替。证毕。真
阅读全文
摘要:题意:给你一些钱去投资,现在有n种股票,每种股票都有一个价值和年收益,问你如何投资在d年后的最大收益并且股票的价值都是1000的倍数,预处理:对每个价值除以1000,减少内存。完全背包,每投资一年,你的钱会变多,即背包总容量会变大。对每一年的资金进行完全背包,然后更新背包总容量,d次循环后得出答案dp上界:每次投资最多获利本金的10%,所以先写个程序计算出dp上界 1000000.0*pow(1.1,40)/1000=45259View Code #include<stdio.h>#include<string.h>#include<algorithm>us
阅读全文
摘要:题意:给6个纸币面额,求出用最少的这6个纸币凑出1-100的面值,求这1-100需要的纸币数种的最大值。解题思路:2个完全背包。注意点:(1)可以相加也可以想减,(2)注意上限,考虑极端数据1 95 96 97 98 99。貌似计算出48次数最多,大概估计不超过30次,所以dp开30*100,如果懒得考虑,直接开100*100。AC代码:View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define maxn 3000#define INF
阅读全文
摘要:经典混合背包 题目给了很多类别的物品。用数组dp[i][j],表示第i组,时间为j时的快乐值。每得到一组工作就进行一次DP,所以dp[i]为第i组的结果。 第一类,至少选一项,即必须要选,那么在开始时,对于这一组的dp的初值,应该全部赋为负无穷,这样才能保证不会出现都不选的情况。状态转移方程:dp[i][j]=max(dp[i][j],max(dp[i][j-w[x]]+p[x],dp[i-1][j-w[x]]+p[x]));dp[i][j]: 是不选择当前工作;dp[i-1][j-w[x]]+p[x]: 第一次在本组中选物品,由于开始将该组dp赋为了负无穷,所以第一次取时,必须由上一组的结.
阅读全文
摘要:注意至少取一个,仔细分析一下,此时光靠一个一维数组是不可以完成状态转移的,必须用二维数组或两个一维数组(滚动数组)。建议多用二维数组,二维数组比较好理解,不容易出错,除非数据量太大,二维开不下。当然,如果对状态转移理解的比较深刻可以尝试着写成滚动数组。先讲一讲二维数组的做法:dp[i][j]表示进行到了第i组容量为j所装载的最大价值。则dp[i][j]这个状态必须从dp[i-1][j-w[x]]+p[x] (选了第1个第i组的物品),dp[i][j-w[x]]+p[x](已经选过第i组的物品,这次又选了第i组的物品),dp[i][j](不选这个物品);所以状态转移方程为:dp[i][j]=ma
阅读全文
摘要:题意:给了n个边,要求每条都用上,组成一个三角形,求三角形面积最大值的100倍(取整数);分析:我们可以开个二维数组dp[i][j]来记录三角形的两条边的长度i,j,那么另一条边就是总长度减去i和j。疑问:判定能构成三角形的条件,设p为三角形的半周长,a+b>c 两边同时加上c 则 2*p>2*c即 p>c,同理p>a,p>b。由海伦公式S=sqrt(p*(p-a)*(p-b)*(p*c))也可以得出这结论。View Code #include<stdio.h>#include<string.h>#include<math.h>
阅读全文
摘要:我竟然做了一题水题,浪费我感情啊,5分钟内2个AC(还是1A);1.0-1背包View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int w[22];bool dp[20000000];int main(){ int n, m, i, j, b; while(~scanf("%d%d",&n,&b)) { m=0; for(i=1;i<=n;i++) scanf("%d",&
阅读全文
摘要:二分法:适用于单调函数,单调增或单调减三分法:适用于单峰凸性函数,如二次函数缩写 l:left ,r: right , m1:mid 1,m2:mid2三分法模板:#define eps 10e-6double cal(){}//计算题目所需要的值while(l+eps<r){ m1=l+(r-l)/3; m2=r-(r-l)/3; v1=cal(m1); v2=cal(m2); if(v1<v2)l=m1; else r=m2;}AC代码:View Code #include<stdio.h>#include<string.h>#include<ma
阅读全文
摘要:类似 《hdu 搬寝室》View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int dp[50003][4],a[50003];int main(){ int cas, n, m, i, j; scanf("%d",&cas); while(cas--) { scanf("%d",&n); a[0]=0; for(i=1;i<=n;i++) { scanf("%d"
阅读全文
摘要:经典的区间DPdp[i][j]代表i->j区间内最多的合法括号数状态转移方程:if(s[i]=='('&&s[j]==')'||s[i]=='['&&s[j]==']') dp[i][j]=dp[i+1][j-1]+2;dp[i][j]=max{dp[i][k]+dp[k+1][j]};AC代码:View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace st
阅读全文
摘要:首先申明:这题数据有很大问题当你输入都为负数时,程序就会出错如 2 3-1 -2 -3竟然输出-3。数据库里有都为负数的情况,我用别人AC代码改了一下测试过了,的确有这情况,但答案貌似是错的。又如 2 3-1 2 -3竟然输出1.这让我郁闷了很久。设输入的数组为a[1...n],从中找出m个段,使者几个段的和为最大dp[i][j]表示前j个数中取i个段的和的最大值,其中最后一个段包含a[j]。(这很关键)则状态转移方程为:dp[i][j]=max{dp[i][j-1]+a[j],max{dp[i-1][t]}+a[j]} i-1=<t<j-1因为dp[i][j]中a[j]可能就自身
阅读全文
摘要:思路:把重物从小到大排序,计算出每2个相邻的重物产生的疲劳度,放在p[i]数组中,表示i与i+1这2个重物产生的疲劳度。dp[i][j]表示进行到第i个物品(i前面的物品不一定都选了,跟背包差不多,i表示进行到第i个物品),已经选了j对物品 产生的最小疲劳度。初始化:先把所有值赋值为INF(无穷大),然后dp[i][0]=0;(0<=i<=n)因为没选重物之前疲劳度为0; for(i=0;i<=n;i++) for(j=0;j<=k;j++) dp[i][j]=INF; for(i=0;i<=n;i++)dp[i][0]=...
阅读全文
摘要:dp[i][j]记录疲劳度用了i,杀了j个怪所获得的最大经验。View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int dp[103][103];int w[103],p[103];int main(){ int n, m, k, s, i, j, x; while(~scanf("%d%d%d%d",&n,&m,&k,&s)) { for(i=1;i<=k;i++) scanf(&q
阅读全文
摘要:用dp[j]记录用j块钱最小不录取的概率。初始化dp[]都为1.0,因为没有选录取的概率为0,不录取的概率为1;View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int w[10001];double p[10001],q[10001],dp[10001];int main(){ int m, n, i, j; while(~scanf("%d%d",&m,&n)&&(n||m)) { fo
阅读全文
摘要:中文题,题意自己看。思路:1.如果一开始钱少于5元,不买东西,按原值输出;2.否则,先拿这五块钱买最贵的一份菜(输入菜的价格后用sort排序一下),然后对其它n-1个菜进行0-1背包处理View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;bool dp[1001];int a[1001];int main(){ int i, j, n, m; while(~scanf("%d",&n)&&n) { f
阅读全文
摘要:不解释View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;bool dp[10003];int main(){ int cas, m,a[4]={0,150,200,350}; int i, j; scanf("%d",&cas); while(cas--) { scanf("%d",&m); memset(dp,0,sizeof(dp)); dp[0]=1; for(i=1;i<=
阅读全文
摘要:完全背包这里要装满,所以要注意dp初始化:dp[0]=0;当求背包最小值时dp[i]=INF(无穷大) (1<=i<=n);反之 dp[i]= -INF(无穷小) (1<=i<=n);View Code #include<stdio.h>#include<string.h>#include<algorithm>#define INF 1000000000using namespace std;int dp[10003],p[503],w[503];int main(){ int cas,i ,j, m, n, x, y; scanf(
阅读全文
摘要:一些二进制的基本知识:判断j是否属于集合i:i&(1<<j)在集合i中去除j:i-(1<<j)或者i&(!(1<<j)) i^(1<<j)在集合i中加入点j:i|(1<<j);先预处理出len[i][j]表示第i个字符串与第j个字符串组合能匹配的最大字符数用一个数的二进制来表示那些字符串,那些字符串还没有选,即二进制位为1 的表示已经选了,为0的表示还没有选Dp[i][j]代表当选取的字符串为i状态,且最后一个选取的字符串是第j个字符串时的最优值状态转移:枚举某个状态时,枚举一个已选的字符串(即当前状态二进制位为1的位
阅读全文
摘要:仔细想一想,必须先要从a_i最小的开始装,这样才能保证高度最高,先根据a_i的大小对每个塔的信息整体进行从小到大排序,然后就是多重背包问题。多重背包不懂的去百度搜《背包九讲》,第4讲就是多重背包,水过。View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int n;bool dp[40003];struct node{ int a, h, c;}p[43];bool cmp(node a, node b){ return a.a<b.a;
阅读全文
摘要:赤裸裸的0-1背包问题,入门题啊View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int dp[12883];int w[3400],p[3400];int main(){ int n, m, i, j; while(~scanf("%d%d",&n,&m)) { for(i=1;i<=n;i++) scanf("%d%d",&w[i],&p[i]); memset
阅读全文
摘要:多重背包看了《背包九讲》,此题1A,爽!!!根据《背包九讲》提供的伪代码:procedure MultiplePack(cost,weight,amount) if cost*amount>=V CompletePack(cost,weight) return integer k=1 while k<num ZeroOnePack(k*cost,k*weight) amount=amount-k k=k*2 ZeroOnePack(amount*cost,amount*weight)自己写一个吧,哈哈...
阅读全文
摘要:背包问题九讲 v1.0目录第一讲 01背包问题第二讲 完全背包问题第三讲 多重背包问题第四讲 混合三种背包问题第五讲 二维费用的背包问题第六讲 分组的背包问题第七讲 有依赖的背包问题第八讲 泛化物品第九讲 背包问题问法的变化附:USACO中的背包问题前言本篇文章是我(dd_engi)正在进行中的一个雄心勃勃的写作计划的一部分,这个计划的内容是写作一份较为完善的NOIP难度的动态规划总结,名为《解动态规划题的基本思考方式》。现在你看到的是这个写作计划最先发布的一部分。背包问题是一个经典的动态规划模型。它既简单形象容易理解,又在某种程度上能够揭示动态规划的本质,故不少教材都把它作为动态规划部分的第
阅读全文
摘要:背包DP题意:有一杆秤,秤上有c个挂钩(2<=c<=20)(在左为负,在右为正,范围-15—15),另有g(2<=g<=20)个砝码(质量各不相同,范围1-25),要 求把所有砝码挂到挂钩上能使秤平衡的种数。分析:每个砝码必须放在c个挂钩上的其中一个。用数组dp[i][j](j表示一个状态,力矩+7500)表示放完第i个砝码后,各个状态存在的种数;确定数组范围:显然0<=i<=20,而对于j,取最极端的数据, 挂钩在15位置,g=20,质量都为25,则计算得力矩最大值15*25*20=7500;挂钩在-15时,同理得力矩最大值-7500;为了避免出现负数,j
阅读全文
摘要:简单DP用dp[i][j]表示第i个苹果掉落,刚好走了j步能吃到苹果的最大值读入时把两颗树的标号1,2处理成0,1,以下说的树的编号都是处理后的0,1;用num[i][2]来记录第i个秒掉落在两颗数的苹果个数,掉落在树0,则num[i][0]=1,num[i][1]=0,掉落在树1,则num[i][1]=1,num[i][0]=0;(num[]数组记得初始化);dp[][]数组初始值: if(num[1][0]==1)dp[1][0]=1; dp[1][1]=1;状态转移:当j=0时,dp[i][j]的前一个状态只能是原地不动(且一定在树0位置)dp[i-1][j],所以dp[i][j]=dp
阅读全文
摘要:类似背包DP。用dp[i][j](bool类型)来表示前i个数组成的和对k取模的值是否存在;状态转移方程为:if(dp[i-1][j])dp[i][get(tmp-j)]=dp[i][get(tmp+j)]=1;//get:自己写个取模函数,注意负数取模-5%7=2AC代码:View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;bool dp[10003][103];int k;int get(int x){ return x < 0 ?
阅读全文
摘要:简单DP题意:由0-k这些数字组成的长度为n的数(并满足某个条件)的个数占所有总数的比例。(满足某个条件:各个位的数字与其相邻的数字之差不超过1.)用数组dp[i][j]表示满足以j结尾,长度为i的数的个数;则适当思考可以得状态转移方程为 : dp[i][j]=dp[i-1][j-1]+dp[i-1][j]+dp[j+1]; (0<j<k) dp[i][j]=dp[i-1][j]+dp[i-1][j+1]; (j==0) dp[i][j]=dp[i-1][j]+dp[i][j-1]; (j==k)这里要考虑是不是边界AC代码Vi...
阅读全文
摘要:神奇的DP:用2个数组r[i],l[i]表示以第i个矩形的高度并包含这个矩形所组成的最大矩形的左右宽度的边界位置;扩展左边界:1。如果第j个矩型的高度比第i个矩阵(1<j<i)的高度低则做边界位置为i,即l[i]=j+1,终止;2。如果高(或相等),则继续向左扩展,直到符合条件1。就终止。扩展右边界:类扩展左边界。以下对于扩展左边界的解释:n(100000)数据很大,如果用以下方法做(类似暴力吧),我们模拟一下发现,如果第j个矩阵扩展的左边界已经得到,在扩展其他第i(i>j)个矩阵时做了很多第j个矩阵扩展的操作,重复了,这样做 无疑 地TLE了;错误做法:for(i=1;i&
阅读全文
摘要:本题关键是建图,然后SAP水一个建图:设0为源点,1为汇点,所以检索表里的插头下标要从2开始。先输入n个插座,每个插座与汇点相连,值为1。再输入m个用电器,用电器的名称其实是个无用的信息,把每个用电器的插头与源点相连,值为1。然后输入k个转换器,如B X,则B与X连,注意值为INF(无穷大),因为这种类型的转换器可以有无数个。最后SAP水一个,水题鉴定完毕。View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define INF 100000
阅读全文
摘要:sap模板题,输入比较麻烦,漏了个分号检查了半天View Code #include<stdio.h>#include<string.h>#include<algorithm>#define maxn 105#define INF 100000000using namespace std;int c[maxn][maxn],dis[maxn],num[maxn];int pre[maxn];int s, t, vs;int n, m, np,nc;void sap(){ memset(dis,0,sizeof(dis)); memset(num,0,size
阅读全文
摘要:dinic1719MSView Code #include<stdio.h>#include<string.h>#include<algorithm>#include<queue>using namespace std;#define INF 1000000#define maxn 250int dis[maxn][maxn];int c[maxn][maxn];bool vis[maxn];bool sign[maxn][maxn];int K,C,M;int s, t, n;void floyd(){ int i, j, k; for(k=1
阅读全文

浙公网安备 33010602011771号