随笔分类 - 动态规划
摘要:状态压缩DP,先对M进行质因子分解,记录其次数,然后对M的所有因子进行统计,分别计算每个因子对应的状态(只有当因子的质因子次数和M相同时这一位才置1),也就是说,如果一个数的每一个质因子次数都没有达到M的质因子次数这个数所表示的状态就是0,然后进行状态DP,其实就是递推,不能算是DP,这个用递推会比记忆化搜索要好,因为记忆化搜索的时候要考虑到底要不要取某一个值,取多少个,用异或没有递推的时候用|实现简单View Code 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define
阅读全文
摘要:这道题是说有n个人要上舞台,每个人有自己的权值,每个人的不高兴值为这个人的权值乘以要等的人数,给一个初始的上台序列,有一个栈可以供你使用来调整上台的顺序。找出最优的上台顺序使得不高兴值的和最小。解决方法:区间DP,dp[x][y]表示区间x到y所能取得的最优值,注意这个区间的划分方法View Code 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define N 105 5 #define inf 0x7f7f7f7f 6 using namespace std; 7 int
阅读全文
摘要:给出不超过14个长度不超过20的字符串,要求出一个包含所有字符串的长字符串的最短的长度,根据题目数据范围可以知道要用状态DP,每个二进制位表示一个字符串,而且需要用二维的,dp[i][j]表示以j为开头的剩下的状态为i的最优值,转移方程也很好写。View Code 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define N 15 5 #define inf 0x7fffffff 6 using namespace std; 7 int dp[1<<15][N];
阅读全文
摘要:这道题很容易能看出来要用动态规划,但是背包确实不是很好想,用数组v[i][j]表示到i分钟,已经连续睡了j分钟所获得的价值,这样对于一个特定的点i所有的j就变成了矛盾的了,状态转移方程就很好写了View Code 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define N 505 5 #define M 55 6 #define R 55 7 using namespace std; 8 int dp[N][M],v[N][R]; 9 int val[N];10 int ma
阅读全文
摘要:链接:http://poj.org/problem?id=2373很明显的DP问题,但是如果利用n^2的算法,肯定会超时,dp[i]表示覆盖到i时的最优值,显然i是偶数,而根据题目描述可以知道,对于一个点i因为每一个覆盖的范围可以调节,而且有最大值和最小值,那么这个解的最优子结构肯定在一个区间里面,这样就可以考虑利用单调队列进行优化,单调队列记录的是在从一个点i开始的往前2*b-2*a的单调递增序列。View Code 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include
阅读全文
摘要:链接:http://acm.hdu.edu.cn/showproblem.php?pid=4001亚洲区预选赛大连赛区的网络赛题目,简单的DP,首先按照长度宽度和id值进行一遍排序,这一遍排序虽然保证不了在第i个前面的都是可以被第i个放到其上面的,但是保证了在第i个后面的都是不可以的。排序之后的dp[i]表示第i个放上之后的最优值。View Code 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cstdlib> 5 #define N 1005 6
阅读全文
摘要:这样类型的题,我觉得应该归类为递推的dp,dp[j][k]表示选j个人达到k=|D(j)-P(j)|时的最大的D(j)+P(j)并且用path[j][k]记录最后一步的选择的编号,输出的时候要对路径上的点进行一遍升序的排序。而且为了能够处理绝对值的问题,加一个修正值fix=m*20则得到的结果都在这个fix的两边,此时fix相当于坐标原点,并且这里要用到一个和修正值有关的公式设div为D(j)-p(j)+fix,我们可以从dp[j][k]里得到D(j)+P(j),则D(j)和P(j)可以用fix,div,以及dp[j][k]表示出来。View Code #include<iostream
阅读全文
摘要:现在在poj上做题,总是要看解题报告,特别是自己没做过的类型,实在是受不了,只能说自己做的题太少了,还不能熟练,这个也是区间dp,这几道区间dp都要求输出最后的结果,必须进行记录,确实麻烦很多View Code 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define N 110 5 #define inf 0x7fffffff 6 using namespace std; 7 char str[N]; 8 struct node 9 {10 int num;11 char s
阅读全文
摘要:区间dp,dp[i][j]表示i-j所需要的最少要加的括号数,并且记录路径,输出的时候递归输出View Code 1 #include<stdio.h> 2 #include<string.h> 3 #define N 110 4 #define inf 0x7fffffff 5 char str[N]; 6 int dp[N][N]; 7 int path[N][N]; 8 void out(int i,int j) 9 {10 if(i>j)11 return;12 if(i==j)13 {14 if(str[i]=='('||str[i]..
阅读全文
摘要:链接:http://poj.org/problem?id=1170很经典的状态dp,这道题基本上体现了状态dp的全部处理过程,状态进制的确定过程,主要是根据题中的数据范围,状态产生要根据输入的状态产生,中间状态合法性判断,对状态的计算处理,然后才是dp里的最优子结构选择问题,当然了要保证一个选择只有一种状态,这是肯定的。最后就是结果的处理过程。View Code 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define inf 0x7fffffff 5 #define min(
阅读全文
摘要:状态dp的一道比较简单的题,令dp[i][j]为第i个状态以第j个单词作为结尾所获得的最优解View Code 1 #include<stdio.h> 2 #include<string.h> 3 #define N 11 4 char s[N][N]; 5 int dp[1<<N][N]; 6 int mcs[N][N]; 7 int n; 8 int max(int a,int b) 9 {10 return a>b?a:b;11 }12 void get_mc(int a,int b)13 {14 int len1=strlen(s[a]);15
阅读全文
摘要:题意是说,给一些大理石,每种有num[i]个,判断能否分成两部分,可行性问题,感觉不像是动态规划,中间没有最优子结构这个性质,倒像是纯粹的递推View Code 1 #include<stdio.h> 2 #include<string.h> 3 #define N 60005 4 int bag[7]; 5 int v[N]; 6 bool dp[N]; 7 int main() 8 { 9 int sum;10 int i,j,k,ans;11 int icase=1;12 while(1)13 {14 sum=0;15 ...
阅读全文
摘要:这是这道题的二进制转化的解法,效率明显要高很多View Code 1 #include<stdio.h> 2 #include<string.h> 3 #define N 100005 4 #define M 18 5 int a[N]; 6 int v[N]; 7 int wei[N]; 8 int max(int a,int b) 9 {10 return a>b?a:b;11 }12 int main()13 {14 int n,m,w,c,t,i,j,k,weight,val;15 int x,y;16 scanf("%d",&
阅读全文
摘要:这是一道有依赖的背包的经典题目,考虑到每个物品最多有两个子物品,最多会有四种状态,所以可以转化为01背包进行枚举状态View Code 1 #include<stdio.h> 2 #include<string.h> 3 #define N 3250 4 #define M 65 5 int a[N]; 6 int s[M][4]; 7 int v[M][3]; 8 int max(int a,int b) 9 {10 return a>b?a:b;11 }12 int main()13 {14 int n,m;15 int i,j,k;16 int f;17..
阅读全文
摘要:链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191多重背包题目,转化为01背包求解View Code 1 #include<stdio.h> 2 #include<string.h> 3 #define N 105 4 int a[N]; 5 int wei[N]; 6 int pri[N]; 7 int b[N]; 8 int max(int a,int b) 9 {10 return a>b?a:b;11 }12 int main()13 {14 int t;15 int n,m,i,j,k;16 scanf..
阅读全文
摘要:链接:http://acm.hdu.edu.cn/showproblem.php?pid=1114这道题是要找最小的可能值,所以初始化的时候要注意一下不同。完全背包的题,要注意总结这些模版题View Code 1 #include<stdio.h> 2 #include<string.h> 3 #define MAXA 1000000000 4 #define N 10005 5 #define M 505 6 int a[N]; 7 int wei[M]; 8 int val[M]; 9 int min(int a,int b)10 {11 return a<b
阅读全文
摘要:链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602最基本的01背包问题,现在发现需要好好的搞搞基础题了,校赛的一个多重背包竟然没做出来。View Code 1 #include<stdio.h> 2 #include<string.h> 3 #define N 1005 4 int a[N]; 5 int v[N]; 6 int val[N]; 7 int max(int a,int b) 8 { 9 return a>b?a:b;10 }11 int main()12 {13 int t,n,i,j,k,m;14
阅读全文
摘要:链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1338很明显,这是一道动态规划的题,但是建议这道题最好用记忆化搜索去做,这样可以避免访问很多不可达的状态,也避免了很多判断,更可以增加时间效率View Code 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define N 105 5 using namespace std; 6 typedef long lo
阅读全文

浙公网安备 33010602011771号