dp
zhengdd1
There is nothing sadder than a dream delays until it fades forever
展开
-
cqm 解题报告e
http://acm.cqu.edu.cn/oj/problem_show.php?pid=21463这题本人较弱。。赛间只会TLE的算法。赛后看标程才会的。 下面附上代码。#include<iostream>#include<algorithm>#include<queue>#include<cstdio>#include<cstring>using namespace std;c原创 2016-05-09 21:40:51 · 351 阅读 · 0 评论 -
石头合并学习区间dp
区间动态规划问题一般都是考虑,对于每段区间,他们的最优值都是由几段更小区间的最优值得到,是分治思想的一种应用,将一个区间问题不断划分为更小的区间直至一个元素组成的区间,枚举他们的组合 ,求合并后的最优值。 设F[i,j](1<=i<=j<=n)表示区间[i,j]内的数字相加的最小代价 最小区间F[i,i]=0(一个数字无法合并,∴代价为0)每次用变量k(i<=k<=j-1)将区间分为[i,k]和原创 2017-05-04 15:49:19 · 321 阅读 · 0 评论 -
折线分割平面hdu2050
折线分割平面 对于一条折线我们可以清楚的发现有两个面,如果我们现在在加一条直线,那么可以很清晰的看到了我们多增加3个平面,那么如果我们再增加折线的另一部分发现又增加了两个面,所以我们可以得到了5个面,当且仅当i=2的时候,瞎推理了下,发现每增加一条边上是当前是第i个折线的2倍-1,继续增加下一条发现是2倍-2所以我们得到递推式, a[i] = a[i-1] + 2 * i -1 +2*i-2。附原创 2017-04-19 21:38:55 · 246 阅读 · 0 评论 -
折线分割平面hdu2050
折线分割平面 对于一条折线我们可以清楚的发现有两个面,如果我们现在在加一条直线,那么可以很清晰的看到了我们多增加3个平面,那么如果我们再增加折线的另一部分发现又增加了两个面,所以我们可以得到了5个面,当且仅当i=2的时候,瞎推理了下,发现每增加一条边上是当前是第i个折线的2倍-1,继续增加下一条发现是2倍-2所以我们得到递推式, a[i] = a[i-1] + 2 * i -1 +2*i-2。附原创 2017-04-19 21:38:30 · 274 阅读 · 0 评论 -
超级楼梯hdu2041
超级楼梯#include<bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 1000 + 10;int t;int n;LL a[maxn];void solve(){ scanf("%d",&t); a[0] = 1; a[1] = 1; a[2] = 2;原创 2017-04-19 18:05:51 · 264 阅读 · 0 评论 -
一只小蜜蜂hdu2044
一只小蜜蜂这道题目一开始没看懂,后面发现就是只能往右和相邻的走,然后模拟了下发现其实就是个斐波那契数,大数据要爆int,然后起点和终点没有关系,因为图是固定的,所以我们只需要知道距离差就可以了,附上代码。#include<bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 1000 + 10;int t;原创 2017-04-19 17:14:56 · 267 阅读 · 0 评论 -
母牛的故事hdu2018
母牛的故事 该题一开始就想模拟做,然后模拟了下过程发现了这个数列是1,2,3,4,6,9,13,可以发现递推式a[i] = a[i-3] + a[i-1],这样我们应该就能算出结果.#include<bits/stdc++.h>using namespace std;typedef long long LL;const int maxn =1000 + 10;int a[maxn];int n;原创 2017-04-19 15:37:39 · 245 阅读 · 0 评论 -
hdu2084数塔问题
数塔问题是一个很明显的递推问题,我们可以推出递推式dp[i][j] = max(dp[i+1][j],dp[i+1][j+1)) +a[i][j],我们从下往上递推,所以dp[n][i] = a[n][i](循环位置i n->1 j 1->i),答案很显然是dp[1][1],下面贴上代码。#include<bits/stdc++.h>using namespace std;typedef l原创 2017-04-19 10:54:06 · 261 阅读 · 0 评论 -
滚动数组
01背包 有N元求取K件是的w[i]*v[i]和最大#include<bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 30000 + 10;int n,m;int v[maxn];int p[maxn];int dp[maxn];///用dp[i]表示花费i元的最优解。void solve()原创 2016-11-30 21:31:11 · 259 阅读 · 0 评论 -
DP的见解
这个可以根据你的动归的状态划分阶段,所谓的阶段就是每个状态它由哪些状态转移过来时,这两者的差别,通过状态推导转移再划分阶段,这大概就是基本的动归思想吧,滚动数组其实就是为了优化动归的空间的,有些状态的解虽然由前面转移过来但是我们没有必要将其保存起来,因为我们只需要最终的答案,这样就可以优化,降低DP的空间复杂度,因为动归就是个用空间换时间的典型嘛,但是空间也是有限的。实际一点就是我们每次原创 2016-11-30 21:57:10 · 224 阅读 · 0 评论 -
01背包
01背包 有N元求取K件是的w[i]*v[i]和最大#include<bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 1000 + 10;const int maxn1 = 30000 + 10;int n,m;int v[maxn];int p[maxn];int dp[30][maxn原创 2016-11-29 13:46:15 · 176 阅读 · 0 评论 -
N的整数划分
将整数n分成k份,且每份不能为空,任意两个方案不相同(不考虑顺序)。例如:n=7,k=3,下面三种分法被认为是相同的。1,1,5; 1,5,1; 5,1,1;问有多少种不同的分法。#include<bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 200 + 10;int dp[maxn][maxn];原创 2016-11-29 13:36:55 · 1309 阅读 · 0 评论 -
有N个硬币,每个硬币有无数个,问有多少方案
方法一 ,dp[i][j]表示取前i种硬币满足价值为j的方案数 dp[i][j] =sum(dp[i-1][j-k*a[i]]) k<=j/a[i] /*TASK:moneyLANG:C++ */#include<iostream>#include<cstdio>#include<stack>#include<queue>#include<algorithm>#includ原创 2016-08-23 17:04:37 · 1693 阅读 · 0 评论 -
usaco 01串 Stringsobits
题目背景 考虑排好序的N(N<=31)位二进制数。 题目描述他们是排列好的,而且包含所有长度为N且这个二进制数中1的位数的个数小于等于L(L<=N)的数。你的任务是输出第i(1<=i<=长度为N的二进制数的个数)小的(注:题目这里表述不清,实际是,从最小的往大的数,数到第i个符合条件的,这个意思),长度为N,且1的位数的个数小于等于L的那个二进制数。(例:100101中,N=6,含有位数为1的个原创 2016-08-29 09:13:30 · 514 阅读 · 0 评论 -
USACO/stamps
/* TASK:stamps LANG:C++ */includeincludeincludeincludeincludeincludeusing namespace std;typedef long long LL; const int maxn = 100; const int INF = 0x3f3f3f3f; const int N = 2e6 + 10;int a[maxn]原创 2016-08-28 12:44:51 · 415 阅读 · 0 评论 -
区间dp括号匹配
题目#include<bits/stdc++.h>using namespace std;typedef long long LL;int t;int n;int dp[110][110];string s;bool judge(int i,int j){ if(s[i-1]=='('&&s[j-1]==')' || s[i-1]=='['&&s[j-1]==']') return原创 2017-05-04 17:46:42 · 283 阅读 · 0 评论