POJ 3018
摘要:题意:d维的n个箱子,装同样是d维的礼物,要求用一个套一个的方式装(每一维都要严格小于才能装进去),求最多用多少个箱子。如果不能装下的话就输出“Please look for another gift shop!”题解:由于箱子装下另一个箱子的条件是严格小于,所以装箱的图是一个有向无环图,然后在这上面找最长路即可(需要先对所有箱子的d维指数排序)。View Code 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int head[60
阅读全文
POJ 2581
摘要:题意:问四种价值硬币是否能凑够某个值,并输出用最少硬币的。(硬币有个数限制)题解:多重背包,先将要凑成的小数化为整形即可。View Code 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int dp[700]; 6 int pr[700]; 7 int main() 8 { 9 int a,b[5],c[5]={25,10,5,1},op[50];10 char s[100];11 op[25]=0;op[10]=1;op[5]=2
阅读全文
POJ 3181
摘要:题意:给出n和m,求[1,m]的数中有多少种的和是n题解:解法不是重点,就是一个简单的背包问题,dp[j+i]+=dp[j],1<=i<=m。问题是n<=1000,m<=100,超long long了,所以java BigInteger一水OK。View Code 1 import java.math.*; 2 import java.util.Arrays; 3 import java.util.Scanner; 4 class Main{ 5 static BigInteger dp[]=new BigInteger[1005]; 6 public static v
阅读全文
POJ 2264
摘要:题意:给出两个字符串,求新的长度最小的字符串,使得给出的两个字符串均是它的子序列。题解:要想最小,就是让两个字串合并起来时相同排列的尽可能合并成一个,即最长公共子序列。所以先求一遍最长公共子序列s,同时记录串s第i位分别是给出的两个字符串s1和s2的哪一位,如果对于s的第k位,对应于s1串的第i位,那么位于s1串i位之前未写进答案串的所有字符均应当在s[k]之前写进去,s2同理可得。View Code 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace
阅读全文
POJ 2193
摘要:题意:一个长度为n的数列(a1,a2...an),满足a[n]<=m&&a[i]>=2*a[i-1],给你n,m,求满足要求数列个数。题解:dp[i][j]代表长度为i且a[i]=j的数列的种数,sp[i][j]代表长度为i且a[i]<=j的种数。dp[i][j]=sum(dp[i-1][k])(k<=j/2),sp[i][j]=sp[i][j-1]+dp[i][j];View Code 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #in
阅读全文
POJ 1143
摘要:题意:两个人玩游戏,初始集合S为大于1的正整数集,轮流写出一个大于1的数然后将:“1、所有这个数的倍数;2、这个数的倍数与前面已经删去的数的和”从集合S中删去,现在告诉你S的现状,求所有必胜走法的第一步。题解:数的数量小于20,可以用位压缩dp,记录S中还剩哪些元素时是否是必胜态,然后通过记忆化搜索求出所有走第一步后是必败态的策略。View Code 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int dp[(1<<20
阅读全文
POJ 1180
摘要:题意:一台机器要按照顺序完成n个任务,每个任务都有一个代价f和需要时间t。机器完成任务的方式是分批处理,对于每一批任务需要首先预处理s时间,同批任务中所有单个任务都是同时完成,代价为完成的时刻乘以各自的代价。求最小代价。题解:类似于四边形不等式的dp。 1、分批考虑情况太多,可以先将问题转化。每个任务对对最后代价的贡献实际上等于它及它以后的f之和乘以它的时间t,即后面的任务都要为它等上t的时间,会多花f*t的代价。 2、找i的决策点的方法即min(dp[p]+(st[i]-st[p]+s)*sf[i]),st[i]为>=i的时间总和,sf[i]为大于等于i的代价总和,若两个决策点,j..
阅读全文
POJ 1848
摘要:题意:给定一棵树,要添加一些边,不能是重边,不能是自环,让它的每一个结点都恰好属于一个环,求最少添加的边数。题解:树形dp:dp[now][0]为以now为根的子树完成题目要求添加的最少边。 dp[now][1]为除开now这个结点后它的子树满足题目要求所需要的最少边。 dp[now][2]为now和它的某一个孩子形成至少长度为2的链所需要添加的最少边,未涉及到的点均已满足题目要求。 转移方程:dp[now][1]=sum(dp[k][0]),k为now的孩子。 dp[now][2]=sum(dp[k][0])-dp[i][0]+min(dp[i]...
阅读全文
POJ 1252
摘要:题意:给6种不同面额硬币,求组成[1,100]中数的平均需要硬币与最多需要硬币数,可以通过减法获得,比如有1、4两种硬币,凑成3可以用4-1两个硬币完成,而不是1+1+1三个硬币。题解:背包问题,由于可以减,还需要反过来dp一遍,值得注意的是上界需要设成2000才行。View Code 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int dp[2050]; 6 void update(int v) 7 { 8 if(v>0)
阅读全文
POJ 3257
摘要:题意:牛要建立长为n的云霄飞车,可以有m个事件点,每个事件设计4个变量,即从a点开始,长为b,给牛f的开心值,要花费c元。牛总共有b元,它们想从0开始,一直经历事件点到最后,使得开心值最大,求此值。题解:对每个事件点建立一条边,同时用dp[i][j]代表第i个点话费了j的钱所能得到的最大开心值,然后用类似dijiskra的算法,从0到n-1开始松弛,再从dp[n][..]中选一个最大的即可。View Code 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namesp
阅读全文
POJ 2955
摘要:题意:给一个括号串,求最大匹配。题解:记忆化搜索,dp[i][j]为[i,j]的最大匹配,dp[i][j]=max(dp[i+1][j-1]+corr(s[i],s[j]),dp[i][k]+dp[k+1][j]);View Code 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int dp[105][105]; 6 char s[105]; 7 int corr(char a,char b) 8 { 9 if((a=='(
阅读全文
POJ 1390
摘要:题意:给定n个不同颜色的盒子,连续的相同颜色的k个盒子可以拿走,权值为k*k,求把所有盒子拿完的最大权值。题解:记忆化搜索,dp[ll][rr][kk]代表在区间[ll,rr]取盒子,其中ll前面有k个盒子颜色和rr一样,可以重叠在rr上消去。 那么,dp[ll][rr][kk]=max(dp[ll][i][kk+len[rr]]+dp[i+1,rr-1][0],dp[ll][rr-1][0]+pow(len[rr]+kk)),i是所有位于[ll,rr-1]区间且与rr颜色相同的盒子;View Code 1 #include<cstdio> 2 #include<cstrin
阅读全文
POJ 1155
摘要:题意:给定一棵树,树的边带负权,树的叶子带正权,求一棵子树,要求涵盖尽可能多的叶子,同时保证总权值不为负题解:树形DP,dp[i][j]代表以i为根的子树含有j个叶子结点时最大权值,对每一个i的子树,dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[t][k]-c)View Code 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 using namespace std; 6 const int N=3005,i
阅读全文
POJ 1192
摘要:题意:题目叙述很长,但很简单,其实如果是英文题倒还可以狠狠的恶心一下人的= =!就是给一个无向树,求最大权子树题解:树形dp,dp[i][0]代表不要第i个点时以i为根的子树的最大价值,dp[i][1]代表必须要i时以i为根的子树的最大值。于是dp[i][0]=max(dp[i][0],dp[j][0],dp[j][1]),j为i能到的点,dp[i][1]=val+sum(max(dp[j][1],0)),即取所有权值为正的i的子树与它相连,注意必须是dp[i][1],因为要保证树最后的连通性。View Code 1 #include<cstdio> 2 #include<c
阅读全文
POJ 3071
摘要:题意:2^n支球队按照竞赛图踢足球,给你任意两支球队相互之间踢赢的概率,求最后那支球队最可能夺冠。题解:dp[j][i]代表第j支球队通过第i场比赛的概率,然后dp[j][i]=sum(dp[j][i-1]*dp[j+k][i-1]*p[j][j+k]),k是它这一场可能面对的对手,实际上就是它上一场比赛的第一支队伍+2^(i-1)一直到+2^i。View Code 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 double p[(1
阅读全文
POJ 2626
摘要:题意:每个人都可以派去下黑棋或者下白棋,但不能都下,然后每人都有各自擅长度,最后选出30人,15人下黑棋,15人下白棋,使得下白棋的擅长度加上下黑棋的擅长度之和最大。题解:dp[i][j]代表i个人下黑棋,j个人下白棋的最大价值,转移方程即为max(dp[i][j],dp[i-1][j]+a,dp[i][j-1]+b),需要注意这是0,1背包,所以要从大往小dpView Code 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int
阅读全文
POJ 1976
摘要:题意:一维序列,用三个相等长度区间区覆盖,使得覆盖的权值最大题解:dp[i][j]为前i个数用j个区间覆盖的最大值,状态转移分为覆盖第i个数和不覆盖第i个数两种。View Code 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int dp[50005][4],sum[50005]; 6 int main() 7 { 8 int T; 9 for(scanf("%d",&T);T;T--)10 {11 in
阅读全文
HDOJ 4276
摘要:先将1到n的路径上的点进行缩点,总时间减去该路径长度,然后这道题就和ZOJ 3626一模一样了,也就是,树形DP。。View Code 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int head[200],nc,dp[200][600],v[200]; 6 struct edge 7 { 8 int to,cost,next; 9 }edge[1000]; 10 struct data 11 { 12 int a,b,c; 13
阅读全文
POJ 1270
摘要:dfs输出原图所有拓扑序就行了。#include<cstdio>#include<cstring>#include<cctype>using namespace std;int d[30],head[30],nc,n;struct edge{ int to,next;}edge[200];void add(int a,int b){ edge[nc].to=b;edge[nc].next=head[a];head[a]=nc++;}char ans[30];void dfs(int k){ if(k==n) { puts(ans); retu...
阅读全文
POJ 1695
摘要:直接DP,做完看别人说是用类似于双调欧几里得旅行商问题一样的方法解,仔细一看我的代码,貌似也和那旅行商问题做法差不多~~这题坑爹之处在于,不能用floyd去优化,也就是说说好了从a到c是99,然后你不能靠先到b再到c来优化。。View Code 1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 using namespace std; 5 int cos[50][50],dp[2][33][33][33]; 6 struct data 7 { 8 int x,y,z; 9 data() {}
阅读全文
|
|
|