动态规划dp
文章平均质量分 69
yrleep
大学毕业不久,ios游戏自由开发者。
展开
-
Codeforces Round #216 (Div. 2) D. Valera and Fools
这个题目很多人都是用记忆化搜索的办法来做的,确实这样比较不容易错并且好写。不过我用了另外一种办法,枚举加判断,判断dp[i][j]是否可行,首先计算前j-1个人死亡的最少回合数,然后再看看后i个人是否不存在神枪手,再判断j号人物是否具有杀伤力,然后再把之前的回合数加上杀死j到i的人的回合数,看看是否比k小,如果这些条件都满足,则这个状态可达。然后剩下的问题就是怎么计算前j-1个人死亡的原创 2013-11-30 13:21:12 · 1265 阅读 · 0 评论 -
poj 1991 Turning in Homework dp
这个可以证明必须从两边的任务开始交起,因为中间交的任务可以后面经过的时候再交,所以就变成了一个n*n的dp。#include #include #include #include using namespace std;const int maxn=1e3+9;int dp[maxn][maxn][2];struct D{ int x,t; bool opera原创 2013-09-02 21:14:29 · 1452 阅读 · 0 评论 -
hdu 4714 Tree2cycle dp
用树形dp做的,dp[t][i]表示t及其孩子入度都已经小于等于2并且t这个节点的入度等于i的最优解。那么转移什么的自己想想就能明白了。关键在于这个题目会暴栈,所以我用了一次bfs搜索出节点的顺序,然后再计算。#include #include #include using namespace std;const int maxn=1e6+9;struct{ int原创 2013-09-08 21:48:21 · 942 阅读 · 0 评论 -
poj 2228 Naptime dp
这个题目的状态还是比较好想的,dp[i][j]表示已经睡了i个时段,最后睡在j时段的最优值,但是需要处理环的情况,我的做法是算两次,第一次不处理环,第二次强制性要求第一个时段需要睡,然后查看dp[m][n]+a[1]的值是否更优。#include #include #include using namespace std;const int maxn=4e3+9;int a[maxn原创 2013-08-30 11:49:20 · 1304 阅读 · 0 评论 -
hdu 3507 斜率优化dp
简单的斜率优化 但是要注意数据中有0,要特殊处理一下。#include #include #include using namespace std;const int maxn=5e5+9;long long sum[maxn],dp[maxn];int que[maxn];bool chk1(int k,int j,int i){ return (dp[j]-dp[原创 2013-08-18 18:37:26 · 697 阅读 · 0 评论 -
hdoj 2829 Lawrence 四边形不等式优化dp
dp[i][j]表示前i个,炸j条路,并且最后一个炸在i的后面时,一到i这一段的最小价值。dp[i][j]=min(dp[i][k]+w[k+1][i]) w[i][j]表示i到j这一段的价值。#include #include #include using namespace std;const int maxn=1e3+9;int a[maxn];long long dp[原创 2013-08-18 15:01:13 · 664 阅读 · 0 评论 -
poj 3709 K-Anonymous Sequence 斜率优化dp
斜率优化dp 注意分母为0的情况#include #include #include using namespace std;const int maxn=5e5+9;long long a[maxn];long long dp[maxn],sum[maxn];int que[maxn];bool chk1(int k,int j,int i){ long long原创 2013-08-16 01:37:25 · 826 阅读 · 0 评论 -
poj 2137 Cowties dp
其实说白了是一个两头的点做状态的dp,但是换成枚举起点的写法会更直接,所以先枚举起点,然后dp到终点。#include #include #include #include using namespace std;const int maxn=1e2+9;int x[maxn][41],y[maxn][41],lon[maxn];double dp[maxn][41];dou原创 2013-08-28 14:21:53 · 1009 阅读 · 0 评论 -
poj 3265 Problem Solving dp
这个题目容易让人误以为是贪心就可以解决了,但是细想一下很容易举出反例。dp[i][j]表示解决了i个问题,最后一个月解决的问题数目。#include #include #include using namespace std;const int maxn=3e2+9;int a[maxn],b[maxn];int suma[maxn],sumb[maxn];int dp[ma原创 2013-08-27 17:30:27 · 963 阅读 · 0 评论 -
poj 1180 斜率优化dp
这个题目要是顺着dp的话很难做,但是倒着推就很容易退出比较简单的关系式了。dp[i]=min(dp[u]+(sum[u-1]-sum[i-1]+s)*f[i]);dp[i]代表从i到结尾需要花费的代价,sum[i]表示1到i的时间和,f[i]代表i到n的代价和。然后对于i状态来说,j由于k等价于 (dp[j]-dp[k])/(sum[k-1]-sum[j-1])然后f[i]随着i递原创 2013-08-16 15:49:27 · 560 阅读 · 0 评论 -
poj 3260 The Fewest Coins
我的做法,一次多重背包得出dp[i]表示john凑够i的钱需要几张硬币,再一次完全背包得出店家的情况。然后枚举john给的钱数。因为john给的钱上限比较难以确定,所以直接开了t的3倍。#include #include #include using namespace std;const int maxn=1e2+9;int v[maxn],c[maxn],vv[maxn*15原创 2013-08-27 19:04:22 · 768 阅读 · 0 评论 -
poj 1260 Pearls 斜率优化dp
这个题目数据量很小,但是满足斜率优化的条件,可以用斜率优化dp来做。 要注意的地方,0也是一个决策点。#include #include #include using namespace std;const int maxn=1e2+9;int dp[maxn];int a[maxn],p[maxn],sum[maxn];int que[m原创 2013-08-15 14:29:18 · 712 阅读 · 0 评论 -
poj 3272
题意不再重复,一条边使用的次数等于从起点走过去的方法数乘以走到终点的方法数。所以就一次正推加一次反推就可以了。#include #include #include #include using namespace std;const int maxn=5e3+9;long long dp[maxn],ans[maxn*10];long long rate[maxn];int h原创 2013-08-26 19:10:53 · 909 阅读 · 0 评论 -
poj 2282 数位dp
数位dp,dp[i][j]表示长度为1到i的数字中一共有多少个j,然后按位统计。#include #include #include #include using namespace std;int dp[10][10];int pow(int a,int b){ int ret=1; for(int i=1;i<=b;i++) ret*=a;原创 2013-08-13 13:59:37 · 799 阅读 · 0 评论 -
poj 2057 树形dp
这个题目需要先推出已知顺序下的递推计算公式,然后再通过计算交换相邻两项的差值来找出贪心的策略。#include #include #include #include using namespace std;const int maxn=1e3+9;int fa[maxn],fb[maxn],leaves[maxn];bool is[maxn];int head[maxn],lo原创 2013-08-24 20:14:42 · 648 阅读 · 0 评论 -
poj 2287 动态规划
用贪心简单证明之后就是一个从两头取的动态规划#include #include #include #include using namespace std;const int maxn=1e3+9;int a[maxn],b[maxn];int dp[maxn][maxn];bool cmp(int a,int b){ return a>b;}int main原创 2013-08-24 14:02:52 · 865 阅读 · 0 评论 -
poj 2411 Mondriaan's Dream dp
一个比较简单的状压dp,记录下每个点的状态即可。#include #include #include using namespace std;const int maxn=13;long long dp[maxn][maxn][2100];int main(){ int n,m; while(scanf("%d %d",&n,&m),n||m) {原创 2013-09-04 21:11:45 · 717 阅读 · 0 评论 -
poj 2373 单调队列优化dp
单调队列优化dp#include #include #include #include using namespace std;const int maxl=1e6+9,maxn=1e3+9;int dp[maxl],que[maxl],top,front;int n,m,l,r;bool use[maxl];struct D{ int l,r; b原创 2013-10-04 16:34:28 · 838 阅读 · 0 评论 -
hdu 4114 dp
ans[i][j],i表示去过的景点和拿到的票的状态,j表示现在在哪个景点。然后spfa即可#include #include #include using namespace std;const int maxn=59;int n,m,p;int cost[10][2];int a[maxn][10],top[maxn];int num[maxn];int tt=0;原创 2013-11-26 22:15:11 · 1011 阅读 · 0 评论 -
hdu 4085 斯坦纳树
#include #include #include using namespace std;const int maxm=11e2+9,maxn=10e1+9;int dp[maxm][maxn],num[maxn],d[maxn][maxn];int n,m,k;bool visit[maxn],chk[maxm];void getdp(){ memset(dp,50原创 2013-11-25 16:59:03 · 1109 阅读 · 0 评论 -
hdu 4123 Bob’s Race 树形dp+单调队列
树形dp求树上最长距离,然后单调队列维护。#include #include #include #include using namespace std;const int maxn=5e4+9;vector > e[maxn];int n,m;int dist[maxn][2];void dfs(int t,int from){ for(vector >::原创 2013-11-24 18:25:33 · 926 阅读 · 0 评论 -
hdu 4089 概率dp
带循环的概率dp但是这个题目的问题是精度很难处理,为什么不特判p4就a不了,表示不能理解。#include #include #include using namespace std;const int maxn=2e3+9;int n,m,k;double p1,p2,p3,p4;double dp[maxn][maxn];void solve(){ mems原创 2013-11-23 16:01:48 · 893 阅读 · 0 评论 -
poj 2151 Check the difficulty of problems dp
概率dp的题目,不过我的做法可能比较不一样,先计算出每个人答对1~n-1,n~m道题目的概率。然后dp[i][0] 表示前i个人,有一个人至少答对n道题,并且每个人至少一个题目的概率。dp[i][1] 表示前i个人,每个人至少答对一道题目的概率。状态转移就很明显了。#include #include #include using namespace std;const in原创 2013-11-22 14:09:33 · 929 阅读 · 0 评论 -
hdu 4248 A Famous Stone Collector dp+组合数学
预处理出c[10000][100],然后dp递推。#include #include #include #define ll long longusing namespace std;const int maxn=1e4+9,mod=1e9+7;ll dp[maxn],c[maxn][111];int a[maxn];int n,sum;ll getdp(){ m原创 2013-11-19 23:32:32 · 1118 阅读 · 0 评论 -
2013 成都 hdu 4784 Dinner Coming Soon dp
这个题目虽然描述的比较麻烦,但是还是不难的,因为t是递增的,所以有拓扑序,那么就可以用dp解了。dp[i][j][p][q] 表示在i点,j宇宙,p时间,q包盐的最优解。但是这个题目最大的问题是让人容易用spfa来解,因为复杂度看起来还是可以的。。。。可是tle到死。#include #include #include using namespace std;const int原创 2013-11-18 22:30:19 · 1035 阅读 · 0 评论 -
poj 3042 Grazing on the Run
这个题目原型应该是吃完所有的草丛的最小时间,现在变成了每个草丛被吃的时间和,貌似如果还是按照原来的dp方法dp[i][j]表示吃完i到j的草丛的花掉的时间的话,有两个因素会影响后面的决策,一个是花掉的时间,一个是吃掉的草丛的时间累加和。但是仔细观察这个问题会发现,第一个走的距离,会被计算n次,第二个走的距离,会被计算n-1次。如果我们把这个代价转移到该草丛上的话。那么dp[i][j]表示转移后原创 2013-10-31 23:51:32 · 1040 阅读 · 0 评论 -
hdu 4427 Math Magic dp
长春现场赛的题目,dp[i][j][k]表示公倍数为i,和为j,用了k个数的方法数。但是状态太多,注意到只有m的约数的公倍数才有可能是m,那么可以预处理出m的所以约数,然后只遍历这些状态,再稍微优化一下常数就可以过了。#include #include #include #include #include using namespace std;const int maxn原创 2013-10-22 11:52:22 · 899 阅读 · 0 评论 -
poj 2430 Lazy Cows 状压dp
这个题目还是比较容易想到用状态dp来解的,但是状态的转移比较麻烦,并且加上有离散化,比较容易出错。dp[i][j][k]表示覆盖前i列,用了j个矩形,当前覆盖状态为k的最优解。k==1:覆盖1号格子k==2:覆盖2号格子k==3:覆盖1,2号格子,并且为同一个矩形k==4:覆盖1,2号格子,并且为不同矩形那么转移的时候就需要考虑,新建矩形,或者直接把当前矩形边长延伸。转移种原创 2013-09-25 16:24:56 · 1363 阅读 · 0 评论 -
poj 3974 Palindrome 最长回文
Manacher算法。不过不知道为什么我写的比比人慢这么多。。。。#include #include #include using namespace std;const int maxn=2e6+9;char a[maxn];int dp[maxn];inline int max(int &a,int &b){ if(a>b) return a; re原创 2013-09-24 11:51:42 · 887 阅读 · 0 评论 -
Codeforces Round #204 (Div. 1) C Jeff and Brackets dp+矩阵加速
比赛的时候没做出来,时间不够,我想到的方法是先求出dp[i][j]在前面有i个左括号的情况下填完n个括号后的最优解。后面的m次就可以用矩阵加速来做了。#include #include #include using namespace std;const int maxn=22;int n,m;int a[maxn],b[maxn];long long dp[maxn][原创 2013-10-08 10:37:10 · 1230 阅读 · 0 评论 -
poj 1848 Tree 树型dp
给一棵数加几条边可以使得每个点都存在且仅存在一个环内算法,说到树一定要注意每个点仅有一个根且没有环这个性质那么就可以知道,如果一个点要向上成环,必须跟树根连接,所以每个点有三个状态是有效的成环,仅仅树根不成环,树根连接下边的一条边不成环,这三中状态去推其他的状态是没有什么大的问题了不再累叙,具体看代码#include#include#includeusing namespa原创 2013-04-14 19:38:56 · 361 阅读 · 0 评论 -
poj 3254 Corn Fields 状压dp
简单的状压dp,用的是按格递推的方式,这样写要比较简单高效一些。#include #include #include using namespace std;const int maxn=13,mod=100000000;int dp[2][8200];inline void add(int &a,int &b){ a+=b; a%=mod;}int m原创 2013-09-20 16:12:20 · 715 阅读 · 0 评论 -
poj 3184 dp
优化常数即可#include #include #include #include using namespace std;const int maxl=1e6+9,maxn=1e3+9;int dp[maxl],que[maxl],top,front;int n,m,l,r;bool use[maxl];struct D{ int l,r; bool原创 2013-10-04 16:35:24 · 915 阅读 · 0 评论 -
poj 2018 斜率优化
斜率优化#include #include #include using namespace std;const int maxn=1e5+9;int que[maxn];long long sum[maxn];bool chk1(int k,int j,int i){ return (sum[i]-sum[j])*(i-k)>(sum[i]-原创 2013-08-15 21:04:40 · 788 阅读 · 0 评论 -
poj 2288 Islands
状态压缩dp,状态不难想dp[tmp][i][j]表示点的状态为tmp,倒数第二个点为i,倒数第一个点为j时的最优解点的状态表示已经加进来的点有哪些这个题目其实卡的地方不少,一个路径数目可以去到13!,要用long long存储第二个 可能只有一个点,那么很多处理都会在这种情况出错,我就用了特判#include#include#includeusing namespace s原创 2013-04-14 19:39:29 · 373 阅读 · 0 评论 -
poj 3378 Crazy Thairs dp
用树状数组优化转移复杂度,结果会超long long,要用高精度。#include #include #include #include typedef unsigned long long ll;using namespace std;const int maxn=5e4+9;ll tree[6][maxn],dp[maxn][6];int a[maxn];int n;ty原创 2013-05-04 02:18:06 · 1004 阅读 · 0 评论 -
poj 2836 rectangle dp(动态规划)
状态dp讲15个点描述成2^15个状态枚举出15*14/2个矩形所能覆盖的点然后状态转移就是每个矩形往上面贴这里边比较麻烦的一点就是如果两个点的横左边或者纵坐标相同,这样它本身不会确定一个矩形所以就要枚举两个宽为1的矩形,这样使得编写麻烦了很多后边仔细想了想,其实只要出现这种情况的时候认为只有这两个点能被包围就行了,原因自己想想就明白了 代码是后边的想法的代码 #include原创 2013-04-14 19:38:14 · 492 阅读 · 0 评论 -
poj 3249 Test for Job dp(动态规…
题目意思是求最短路,但是因为此图没有环,所以可以用动态规划的办法按照拓扑序列递推求解第一次调用系统的链表自己写的链表居然T了...#include #include#include#include#includeusing namespace std;const int maxn=100001;const int inf=1int gain[maxn],dist[maxn];原创 2013-04-14 19:37:32 · 428 阅读 · 0 评论 -
poj 3661 Running dp(动态规划)
一个没有设置障碍的dp简单描述下题意 每一分钟你可以选择跑di米或者休息跑的话疲劳度会+1 休息的话会-1然后在任何时候疲劳度都不超过m的情况下最后一分钟疲劳度为0能跑的最远距离思路: 很容易想到dp,然后dp[i][j][0]表示第i分钟在休息,疲劳度为j的最远距离 dp[i][j][1]表示第i分钟在跑,疲劳度为j的最远距离 然后原创 2013-04-14 19:40:39 · 556 阅读 · 0 评论 -
poj 1952 BUY LOW, BUY LOWER dp
这个题目的dp应该不难想 简单最长下降子序列但是去重这个东西还是有点麻烦的我的想法在dp的过程中去掉重复a[k]存储原序列 f[k]存储方案数当用a[i]去更新新的dp值时遇到相同的值a[j]时,把f[j]置为0。因为这个时候i,j记录的序列是一样的 出现了重复,所以要去重。 #include#include#includeusing namespace std;const原创 2013-04-14 19:40:33 · 502 阅读 · 0 评论