动态规划
vsooda
这个作者很懒,什么都没留下…
展开
-
HDU 2059 龟兔赛跑 思想基本正确,但是没有独立做出来,以后再自我考察 update
主要原因是仅仅考虑了dp[i] = f(i-1, i) + dp[i-1].(其中f(i-1,i)表示从第i-1站到第i站的最短时间)其实未必是从前一个加油站到当前加油站,而应该是dp[i] = f(j, i) + dp[j]; (0 以下是AC代码:#include #include int main (){ int L; int N, C, T; int vr,原创 2012-08-31 10:26:40 · 766 阅读 · 1 评论 -
HDU 2577 how to type
简单动态规划,用两个数组分别保存开灯与不开灯状态,该设置很重要,做题之前要考虑全面。用两个a,b数组分别记录Caps Lock开与关时打印第i个字母的最少操作步骤;而对于第i个字母的大小写还要分开讨论:Ch[i]为小写: a[i]=min(a[i-1]+1,b[i-1]+2);不开灯直接字母,开灯则先关灯再按字母,最后保持不开灯; b[i]=min(a[i-1]+2,b[i-1原创 2012-08-27 10:34:36 · 499 阅读 · 0 评论 -
HDU 1300
Dp[i]=min{Dp[j]+V}, 0题目默认每个输入的价格递增,如果非递增,会麻烦一些。#include #include using namespace std;const int N = 105;const int INF = 9999999;int dp[N];int a[N];int p[N];int sum(int x, int y, int p){原创 2012-09-02 21:43:09 · 1175 阅读 · 2 评论 -
HDU 3008 Warcraft
#include#include#include int skillCost[110];int skillhurt[110];int dp[110];//dp[i][j]表示第i轮攻击,boss还剩下j滴hp时候剩下的最大mpint max(int a,int b){ return a>b?a:b;}int main(){ int n,t,q; while(scanf("原创 2012-09-03 15:48:43 · 793 阅读 · 0 评论 -
HDU 1227 距离和最小,转移方程!
这里需要一个常识:在i到j取一点使它到区间每一点的距离之和最小,这一点为(i+j)/2用图形即可证明;Dp[i][j]=max{Dp[i-1][k]+cost[k+1][j] 其中,(i-1)代码很容易编写:#include #include using namespace std;const int N = 205;const int M = 32;int dp[M][原创 2012-09-03 14:34:04 · 1027 阅读 · 0 评论 -
HDU 1501 高效!
DP解法:最优子结构分析:如上例,如果A、B可以组成C,那么,C最后一个字母e,必定是 A 或 C 的最后一个字母组成。C去除除最后一位,就变成是否可以求出 A-1和B 或者 A与B-1 与 是否可以构成 C-1。。。状态转移方程: 用f[i][j] 表示 表示A前 i 为 和B 前j 位是否可以组成 C的前i+j位 dp[i][j]=原创 2012-09-03 09:50:50 · 2125 阅读 · 1 评论 -
HDU 1422 循环的序列,可以利用输入数据两次解决
这题的状态不难理解,状态表示为,如果上一个城市剩下的钱不为负,也就是没有被赶回杭电,则再考虑它对下一个城市的影响;如果上一个城市剩下的前加上当前城市的前大于当前城市的生活费,那么Dp[i]=Dp[i-1]+1;值得注意的而是这题的数据为100000;不可能以每个城市为起点来一次Dp,时间复杂度为n^2;足已超时;我是这样处理的,在保存的数据后面再接上1…n的数据,这样扫描一遍的复杂度为n;原创 2012-09-02 20:17:31 · 665 阅读 · 0 评论 -
HDU 1224 莫名其妙的WA
先是AC代码#include#include#includeusing namespace std;const int N=105;int father[N];int v[N];int dp[N];bool map[N][N];void print(int n){ if(n==-1)return; print(father[n]); printf("%d->",n)原创 2012-09-02 19:54:43 · 543 阅读 · 0 评论 -
HDU 1074 状态压缩dp
原文地址:http://www.cnblogs.com/Kenfly/archive/2011/03/30/2000364.html题目: http://acm.hdu.edu.cn/showproblem.php?pid=1074题意: 学生要完成各科作业, 给出各科老师给出交作业的期限和学生完成该科所需时间, 如果逾期一天则扣掉一单位学分, 要你求出完成所有作业而被扣最小的学分转载 2012-09-02 09:51:12 · 662 阅读 · 0 评论 -
HDU 1158 雇佣决策 动态规划,只要肯用空间,时间,这题就是简单题
状态表示: Dp[i][j]为前i个月的留j个人的最优解;Num[i]j>Max{Num[i]}之后无意义,无谓的浪费 记Max_n=Max{Num[i]};Dp[i-1]中的每一项都可能影响到Dp[i],即使Num[i-1]所以利用Dp[i-1]中的所有项去求Dp[i];对于Num[i]当k>j时, 解雇 然后求出最小值Dp[i][j]=min{Dp[i-1][k…Max原创 2012-09-01 18:05:40 · 714 阅读 · 0 评论 -
HDU 1080 最长公共子序列变形
要注意i,j的下标是从1开始到n, m在编码过程中,刚开始一直出错,后来发现初始少了两句for(int i = 1; i dp[i][0] = dp[i-1][0] + r[a[i-1]][4];for(int i = 1;i dp[0][i] = dp[0][i-1] + r[4][b[i-1]];#include using namespace std;原创 2012-09-01 20:41:15 · 1235 阅读 · 0 评论 -
HDU 1081 最大子矩阵
#include #include int main() { const int size = 101; int Max,sum; int N,i,j,k,val,a[size][size]; while (scanf("%d",&N)!=EOF) { memset(a,0,sizeof(a)); Max = -128; fo原创 2012-08-31 08:57:14 · 948 阅读 · 1 评论 -
HDU 1502 dp + 大数
dp[i][j][k]=dp[i-1][j][k]+dp[i][j-1][k]+dp[i][j][k-1];同时注意,dp的结果很大,要用到大数。设sum[i]表示当n为i时的结果,即当i==j==k时的结果。(注意:把dp和sum都定义成char型数组,否则会超存)。#include #include #include #include #define N 80us原创 2012-09-05 23:22:38 · 691 阅读 · 0 评论 -
HDU 2845 最大非连续子段和 二维dp
#include #include #include #define Maxn 200001#define Max(a,b) ((a)>(b)?(a):(b))int dp[Maxn][2];//dp[i][0] 表示不取第i个能到的最大值//dp[i][1] 表示取第i个能到的最大值int row[Maxn];int main(){ int i, j, k; int原创 2012-08-28 23:10:51 · 867 阅读 · 0 评论 -
HDU 1503 最大公共子序列,输出用到了递归
#include #include using namespace std;const int N = 102;char a[N], b[N];int dp[N][N];int map[N][N];void printLCS(int i,int j){ if(i==0&&j==0) return; if(i==0) { printLCS(i,j-1); print原创 2012-09-05 22:58:56 · 690 阅读 · 0 评论 -
HDU 3709 ZJU 3416 Balanced Number 数位dp 记忆搜索
参考:http://www.cppblog.com/Yuan/archive/2013/03/09/139299.html#198320用这种方法写,一个流程是,列出式子(pre*10^pos + next) pre是确定的,next是变量 所以参数就为pre,pos加上一些其他的,还有一个标记doing,表示是计算有上界限制的还是没有上界限制(所有情况,即end=9)原创 2013-03-28 16:20:20 · 1134 阅读 · 0 评论 -
HDU 3652 3555 数位dp
/* 求[1,n]内有多少个数字,该数字有13,且能被13整除 n<=10^9 x % 13 = 0 (pre*10^pos + next) % 13 = 0 pre是之前确定的部分 需要的参数为pre , pos , 状态have have记录pre拥有"13",pos+1位为"1",没有"13" 分别用have = 2,1,0表示原创 2013-03-28 16:57:17 · 1244 阅读 · 2 评论 -
HDU 4512 最长公共上身子序列(加强)
dp[i][j] 表示a(1,i),b(1,j)取以a[i], b[j]结尾的最大公共上升子串的大小#include using namespace std;const int N = 205;int dp[N][N];int a[N];int main() { int t; cin >> t; while(t--) { int n; cin >> n; for(原创 2013-03-27 10:14:17 · 1418 阅读 · 0 评论 -
HDU 3247 AC自动机 + 状态压缩dp
小HH:乳鸽的神题,状态很容易看出来,有50000*1024,很难保持,我用散列表超时了,用bitset刚好可以卡过,不过后来我想,只有尾结点才有效,中间的很多结点完全可以忽略,可以先用最短路吧各个尾结点之间的距离算出来,经过测试,不到50个点,马上就优化到50*1024了,本来9s多过的优化到了100多MS#include #include #include #include #in原创 2013-01-18 13:10:36 · 788 阅读 · 0 评论 -
树形dp 和 状态压缩dp
状态压缩动态规划动态规划的状态有时候比较难,不容易表示出来,需要用一些编码技术,把状态压缩的用简单的方式表示出来。典型方式:当需要表示一个集合有哪些元素时,往往利用2进制用一个整数表示。*:一般有个数据 n*:确定了为状态DP,那么第一步就是预处理,求出每行所有可能的状态了,cnt记录总的状态数,stk[]记录所有的可能状态。以炮兵阵地为例:int cnt, stk[MAX];转载 2013-01-16 21:57:45 · 766 阅读 · 0 评论 -
PKU 1185 炮兵阵地 经典状态压缩dp
思路:状态压缩DP。很经典的状态压缩DP。用int型来表示每行的状态(如果int型的二进制的第i位为1,则表示这一行的第i列有安装大炮)。这样的话由于最多有10列,故由计算可得最多有60种状态。DP部分:dp[r][i][k]表示第r行的状态为k,第r-1行的状态为i时候,前r行最多能够安装的大炮数量。 #include#define max(a,b) ((a)>(b)?(a):(b))原创 2013-01-16 21:55:57 · 740 阅读 · 0 评论 -
HDU 2476 字符串a转化为字符串b需要几次操作 结合编辑距离
与编辑距离思想类似,但是编辑距离每次只能增删改。还涉及到字符串的对齐问题。http://blog.csdn.net/vsooda/article/details/8313172而本题每次修改就修改一个区间。自然地,使用dp[i][j]表示从i 到 j 所需要的修改次数的上界。初始化dp[i][j]为dp[i+1][j] + 1如果s2[i] == s2[k] dp[i][j] =原创 2013-01-28 10:09:47 · 1825 阅读 · 0 评论 -
HDU 1423 最长上升公共子序列
参考:http://www.cnblogs.com/nuoyan2010/archive/2012/10/17/2728289.html#include#includeusing namespace std;const int N = 505;int num1[N],num2[N],f[N][N];int main(){ int t,n,m; scanf("%d",&t);原创 2013-01-25 17:15:15 · 3017 阅读 · 0 评论 -
HDU 1025 高效最长上升子序列(二分查)
用到了LIS(Longest Increasing Subsequence)最长上升(不下降)子序列,它有两种算法复杂度为O(n*logn)和O(n^2)。前者使用二分查找,后者朴素查找。它的算法大致思路:设置两个a,b数组,a数组存储数据,b数组存储最长不降序序列。此算法关键在于设计二分查找。刚开始用到了朴素dp算法,果断超时,超时代码为: #include #include usi原创 2012-09-19 10:41:07 · 1433 阅读 · 3 评论 -
HDU 1059 物品价值平分问题,母函数或者多重背包 与 2844类似
#include #include #define Size 60005 #define Max(a,b) a>b?a:b int sum; int dp[Size]; /*01背包*/ void ZeroOnePack(int cost,int weight) { int i; for(i = sum;i>=cost;i--) dp[i]原创 2012-09-01 18:27:01 · 915 阅读 · 0 评论 -
HDU 2037 dp 节目安排,怎么收看最多的完整节目
说是动态规划,其实也有点贪心的思想。一维数组里保存的的就是以当前节目作为开始,最多能完整地看多少个不同的节目。很明显,播出时间最晚的节目只是能1。我采取从后往前的规划方法。这样,当循环到i时,能保证数组里 D[i+1] -> D[n-1] 保存的都是最优解。所以让j 从 i+1 到 n-1 循环,找出看完第i个节目后最多还能看的节目数max。(不要忘了判断能否完整收看哦)原创 2012-09-14 15:49:51 · 758 阅读 · 0 评论 -
HDU 1078 DP + 记忆搜索
dfs!#includeusing namespace std;int gra[101][101];int dp[101][101];//表示从i行j列能够获得的最大收益int n,k;int dir[4][2]={-1,0,1,0,0,-1,0,1};int dfs(int i,int j) //记忆法搜索{ int s,t,p,q,temp,m=0; if(dp[i][原创 2012-08-31 08:30:08 · 593 阅读 · 0 评论 -
HDU 1160 最长下降子序列(错误代码也可能通过,误导啊)
写的代码有点垃圾,改天优化一下。#include #include using namespace std;const int N = 1001;int dp[N];int front[N];int p[N];typedef struct { int weight; int speed; int num;} mice;mice mouse[N];bool cm原创 2012-08-30 20:57:48 · 558 阅读 · 0 评论 -
HDU 1087
#includeint main(){ int n,i,j,a[1000],b[10000],maxb,maxnum; while(scanf("%d",&n),n) { maxnum=0; for(i=0;i<n;i++) { scanf("%d",&a[i]); b[i]=a[i]; } for(i=0;i<n;i++) { b[i]=a[i原创 2012-02-20 14:16:37 · 460 阅读 · 0 评论 -
HDU 1176 !
状态表示:dp[i,j]为j秒时在i位置的最大值//问题描述为:求从f[0][5]到f[T][]的一条路径,使得总和最大状态转移:i=0 dp[0][j] += Max(dp[0][j+1], dp[1][j+1]); i=10 dp[10][j] += Max(dp[10][j+1], dp[9][j+1]); i=1-9 dp[i原创 2012-02-25 20:11:23 · 854 阅读 · 0 评论 -
HDU 2037 vc编译问题
vc不通过,提交通过#include#includestruct c{int x;int y;int ord;}d[100];int cmp(const struct c *a, const struct c *b){ if ((*a).x == (*b).x) return (*a).y - (*b).y; e原创 2012-02-17 12:36:26 · 535 阅读 · 2 评论 -
HDU 1069
#include#include#includestruct rect{ int x; int y; int z;}r[100];int bubblesort(struct rect* r,int n){ int i,j,t=n; struct rect temp; for(i=0;i<n;i++) { for(j=0;j<n-i-1;j++) { i原创 2012-02-25 17:45:11 · 854 阅读 · 0 评论 -
HDU 2159
二维完全背包,第二层跟第三层的要顺序循环;(0-1背包逆序循环);状态可理解为,在背包属性为 {m(忍耐度), s(杀怪个数)} 里最多能得到的经验值,之前的背包牺牲体积,这个背包牺牲忍耐度跟个数注意: 最后扫的时候 外层循环为忍耐度,内层循环为杀怪个数,因为题目要求出剩余忍耐度最大,没有约束杀怪个数,一旦找到经验加满的即为最优解;状态转移方程为: f[j][l]=max(f[j][l],原创 2012-02-25 23:27:20 · 1251 阅读 · 0 评论 -
HDU 1171 ?
题目大意:hdu的计算机要分成两个学院,现在有n种物品,价值为ai的有bi个,要求把这些东西分成价值总和最为接近的两份,如果不能平分,大的在前面。#include using namespace std;int V[51];int M[51];int bst[125005];int main (){ int N; while ( scanf ( "%d",&N ),原创 2012-02-25 19:34:16 · 1100 阅读 · 0 评论 -
HDU 2602
#include#include#define M 1010int a[M],b[M],n,v;int f[M];int max(int x,int y){ if(x<y) return y; else return x;}void pack(int cost,int weight){ int i; for(i=v;i>=cost;i--) { f[i]=原创 2012-02-25 00:09:25 · 598 阅读 · 0 评论 -
HDU 1203
#includeint a[1010];double b[1010],f[10010];double Min(double x,double y){ if(x<y) return x; else return y;}int main(){ freopen("1203.txt","r",stdin); int n,m,i,j; while(scanf("%d%d",原创 2012-02-25 22:07:06 · 1298 阅读 · 0 评论 -
HDU 2571
#includeint a[22][1010],f[22][1010];int max(int x,int y,int z){ if(x>=y&&x>=z) return x; else if(y>=x&&y>=z) return y; else if(z>=x&&z>=y) return z;}int main(){ int n,m,t,i,j,k,c; sca原创 2012-02-25 11:17:00 · 845 阅读 · 0 评论 -
HDU 1505
这题是HDU1506 的加强版,只要把算出以i 行为底能达到的最到的最大高度,再扫描每一行,就转化为 HDU1506 的问题了,即算出以此点为最低点能两边延伸的最大距离,最大延伸距离乘以该点的高度就是面积了,HDU 2870 则是此题的加强版#include#include#define M 1005int a[M][M],l[M],r[M];int main(){ int t,i原创 2012-02-23 21:48:12 · 2490 阅读 · 0 评论 -
HDU 1506
【题目大意】 给出n(n 【解题思路】 对于每一块木板,Area=height[i]*(j-k+1) 设其中任一块x, j=height[i]; 找j,k成为关键。 一般方法肯定超时,[cpp:firstline[1]] view plaincopyFOR i:=1 TO n原创 2012-02-21 16:08:39 · 557 阅读 · 0 评论 -
HDU 1181
#include #include int main() { freopen("1081.txt","r",stdin); const int size = 101; int Max,sum; int N,i,j,k,val,a[size][size]; while (scanf("%d",&N)!=EOF) {原创 2012-02-20 13:39:16 · 424 阅读 · 0 评论