![](https://img-blog.csdnimg.cn/20201014180756922.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
DP
nash142857
这个作者很懒,什么都没留下…
展开
-
ZOJ1499经典dp
参考别人解题报告写得,很经典,开始很容易想到dp,dp[i]记录已i结尾满足递增,并且结尾值最小的长度。 但是如果最后的值相同还需要使得前面的值尽可能大,#include #include char s[90]; int dp[100],n; int gao(int a,int m,int c,int n) { while(s[a]=='0'&&m)a++,m--; while(s[c]==原创 2012-08-29 13:51:54 · 1133 阅读 · 1 评论 -
poj1734 最小环
这道题目是floyd的经典,floyd的核心思想就是动态规划从k=0->n来松弛i->j的路径, 这样我们可以这样思考这个环,里面肯定有最大的下标,设为k,与之相邻的是i和j,然后i->j的最短路肯定在用k松弛前已经更新完,换句话说就是 我们floyd时候先找环再松弛,因为floyd的外层到k时,i->j的最短路上肯定没有k所以这个环不会存在相同的点,代码如下:#include #includ原创 2012-11-02 22:44:49 · 1408 阅读 · 0 评论 -
ZOJ3381
DP+线段树, dp[i]记录从i开始的最大收益, dp[i]=s[i]+max(dp[x]|i+x[i] 利用线段树维护个最大值就行了 #include #define MAXN 50010 #define max(a,b) ((a)>(b))?(a):(b) int n,s[MAXN],x[MAXN],y[MAXN]; int seg[4*MAXN]; int dp[MAXN]; vo原创 2012-09-16 16:30:51 · 520 阅读 · 0 评论 -
ZOJ3305
每个状态压为个二进制数,然后0-1背包。#include #include #include using namespace std; int n,m,ANS,maxn; int dp[1<<16]; int main() { while(2==scanf("%d%d",&n,&m)) { ANS=1<<n; ANS-=1; maxn=0; memset(dp,0,sizeof原创 2012-09-11 19:35:59 · 684 阅读 · 0 评论 -
ZOJ1074
/*经典DP,p[i][j]记录到第i行位置每行第j个数的和,然后算p行到q行的一个最大矩阵,就相当于是个最大和子序列问题*/ #include #include int n; int p[110][110]; int main() { while(scanf("%d",&n)!=EOF) { memset(p,0,sizeof(p)); for(int i=1;i<=n;i++)原创 2012-09-11 16:02:15 · 1192 阅读 · 0 评论 -
hdu3586(二分+树形dp)
以1号点为根树形dp, dp[x]=对每个儿子sum+=min(w(边权),dp[那个儿子]),dp=sum;这个地方要对limit power进行判断。 对于没有解的情况,我是用inf作为标记物表示这个点无法被切断,枚举儿子 如果有个儿子dp[..]=inf并且w>limit power 那么就设置父节点dp[x]=inf 并且return 最后对dp[1]>=m作判断即可(已包括dp[1原创 2012-08-25 20:01:34 · 870 阅读 · 0 评论 -
ZOJ2581
感觉很强的双调dp问题,不会做,看了解题报告才写的,感觉这题做法比较不错 说的是你从左边一个点走到右边一个点再走回来,要把途中的n-2个点走完,问最短路。 做法是假想两个人从左往右走,一起走到右边那个点的总路径,为了方便,不妨设前面那个人走到i,后一个 走到了j,用dp[i][j]表示这种状态的最短路,然后自底而上刷表,如果下一步是前一个走到i+1,更新就是dp[i+1][j]=原创 2012-08-25 18:53:00 · 446 阅读 · 0 评论 -
zoj2963
状态压缩dp这题坑在特判#include #include #include #include using namespace std; struct node { int id; int l; friend bool operator<(node a,node b) { return a.l>b.l;原创 2012-08-25 18:46:59 · 415 阅读 · 0 评论 -
ZOJ2059
经典DP,利用高度差作为下标保存当前的i值下的最高塔的值.出现了低级错误,汗啊、、#include #include int dp[101][2001],n; int max(int a,int b) { return a>b?a:b; } int main() { while(scanf("%d",&n),n>=0) {原创 2012-08-25 18:45:16 · 589 阅读 · 0 评论 -
zoj1462 二分图染色+DP
不认识的人间连边,对于每个连通分量dfs染色 再01背包DP就ok#include #include #include #include using namespace std; vectors[2][150]; int mp[150][150],p[150][150],vi[150],dp[150][150]; int path[150],c[150]; int t,n,cnt; struct原创 2012-09-03 15:51:20 · 570 阅读 · 0 评论 -
ZOJ1463 DP
超坑,思路很简单,dp外加记录下路径之类的。 但有个坑,就是可能输入是空行,所以要gets或则C++getline。 #include #include int n; const int inf=9999999; char s[110]; int dp[110][110],p[110][110]; void print(int i,int j) { if(i>j) return; if原创 2012-09-02 19:15:14 · 721 阅读 · 0 评论 -
ZOJ1303
特别坑的题目,反正我被坑死了,终于AC了, 题目想了下,写错了,然后看下别人的代码发现思路错了(菜啊),然后自己再去写, 随便怎么dp都行,我是外循环从1-》m dp[0||1][j]表示差为j时的最大sum,再用个path记路径就醒了 后来wa的原因想了好久,竟然是滚动数组没层都要memset,忘了,汗!! #include #include #include #define p原创 2012-08-31 14:13:16 · 566 阅读 · 0 评论 -
ZOJ1234+dp
由于选定了第一个数肯定再选接着的数,那么badness才会最小,这样就定下了badness,也就是你选了一个数,那么这个badness就定下来了,所以i要从后向前,j(次数)从前到后,dp下就行 dp[i][j]表示从i->n组成J队的最小badness. #include #include int n,k,t; int num[5010]; int dp[5100][1100]; int m原创 2012-08-29 19:11:38 · 620 阅读 · 0 评论 -
CF #148 DIV2 E
树形DP的不错的题目 枚举第一个点,以此为根dfs,然后对于另一个点v不再路径u-v上的边 全要调成指向树叶,路径上的边,相当于01序列化为11....00 #include #include #include using namespace std; #define N 3100 int dp[N][2],n,sum; struct node { int f,y; }; vectorvt[N原创 2012-11-07 00:25:23 · 595 阅读 · 0 评论