一、线性动态规划

最长严格上升子序列

#include<iostream>
#include<cstdio>
using namespace std;
int n,ans;
int a[5004],dp[5004];
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);for(int i=1;i<=n;i++){for(int j=1;j<i;j++){if(a[j]<a[i])dp[i]=max(dp[i],dp[j]+1);ans=max(ans,dp[i]);}}printf("%d\n",ans+1);return 0;
}

最长严格上升子序列

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=0x3f3f3f3f;
int n,a[1000009],dp[1000009];
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);memset(dp,0x3f,sizeof(dp));for(int i=1;i<=n;i++){int p=upper_bound(dp+1,dp+n+1,a[i])-dp;if(a[i]!=dp[p-1])//严格上升序列 dp[p]=a[i];}for(int i=1;i<=n+1;i++){if(dp[i]==maxn){printf("%d\n",i-1);return 0;}}return 0;
}

nlogn

变形:打鼹鼠

#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
int maxt,n,m,ans,x[10001],y[10001],t[10001],f[10001];
int main()
{int i,j;scanf("%d%d",&n,&m);for (i=1;i<=m;++i)scanf("%d%d%d",&t[i],&x[i],&y[i]);for (i=1;i<=m;++i){f[i]=1;//f表示到第i只鼹鼠出现时最多可以打到多少只 for (j=i-1;j>=1;--j)if (t[i]-t[j]>=abs(x[i]-x[j])+abs(y[i]-y[j]))//如果时间足够,能从j点移动到当前点 f[i]=max(f[i],f[j]+1);ans=max(ans,f[i]);}printf("%d",ans);
}

Luogu打鼹鼠

二、背包

1)01背包

每个物品只有一个且只有选与不选两种可能

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[1002],w[1001],v[1001];
int n,m,t;
int main()
{scanf("%d",&t);while(t--){memset(f,0,sizeof(f));scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&v[i]);for(int i=1;i<=n;i++)scanf("%d",&w[i]);for(int i=1;i<=n;i++)for(int j=m;j>=w[i];j--)f[j]=max(f[j],f[j-w[i]]+v[i]);printf("%d\n",f[m]);} return 0;
}

01背包

2)完全背包

每件物品数量无限

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int w1,w2,wi,t,k,f[10002],v[510],w[510];
int main()
{scanf("%d",&t);while(t--){memset(f,0x3f,sizeof(f));f[0]=0; //**scanf("%d%d",&w1,&w2);wi=w2-w1;scanf("%d",&k);for(int i=1;i<=k;i++)scanf("%d%d",&v[i],&w[i]);for(int i=1;i<=k;i++)for(int j=w[i];j<=wi;j++)f[j]=min(f[j],f[j-w[i]]+v[i]);if(f[wi]==0x3f3f3f3f)printf("This is impossible.\n");elseprintf("The minimum amount of money in the piggy-bank is %d.\n",f[wi]);}return 0;
}

完全背包

3)多重背包

每个物品数量一定

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int t,mon,k,w[102],pri[102],f[102],cnt[102];
int main()
{scanf("%d",&t);while(t--){memset(f,0,sizeof(f));scanf("%d%d",&mon,&k);for(int i=1;i<=k;i++)scanf("%d%d%d",&pri[i],&w[i],&cnt[i]);for(int i=1;i<=k;i++){for(int j=mon;j>=pri[i];j--){for(int h=0;h<=cnt[i];h++){if(j-h*pri[i]<0)break;f[j]=max(f[j],f[j-h*pri[i]]+h*w[i]);}}}printf("%d\n",f[mon]);}return 0;
}

多重背包

4)混合背包

-1为无限个

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
int w[100000],v[100000],c[10000],dp[20000000];
int main()
{int vv,n;scanf("%d%d",&n,&vv);for(int i=1;i<=n;i++)scanf("%d%d%d",&w[i],&v[i],&c[i]);for(int i=1;i<=n;i++){if(c[i]==-1){for(int j=w[i];j<=vv;j++){dp[j]=max(dp[j],dp[j-w[i]]+v[i]);}}else{int x=c[i];for(int j=1;j<=x;j<<=1){for(int k=vv;k>=w[i]*j;k--){dp[k]=max(dp[k],dp[k-w[i]*j]+v[i]*j);}    x-=j;}if(x!=0){for(int j=vv;j>=x*w[i];j--){dp[j]=max(dp[j],dp[j-x*w[i]]+v[i]*x);}}}}printf("%d",dp[vv]);return 0;
}

混合背包

5)二维费用背包

#include<bits/stdc++.h>
using namespace std;
int f[1010][1010];
int main(){int n,m,x;cin>>n>>m>>x;for(int i=1;i<=n;i++){int a,b,c;cin>>a>>b>>c;for(int j=m;j>=b;j--)                                     //以下3行是算法的核心for(int k=x;k>=c;k--)f[j][k]=max(f[j][k],f[j-b][k-c]+a);}cout<<f[m][x];return 0;
}

二维费用

6)有依赖性背包问题

#include<iostream>
#include<cstdio>
using namespace std;
struct e
{int v,p,q,w,f[66];
}g[66];
int n,m,f[35000];
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){scanf("%d%d%d",&g[i].v,&g[i].p,&g[i].q);g[i].w=g[i].v*g[i].p;if(g[i].q!=0)g[g[i].q].f[++g[g[i].q].f[0]]=i;}for(int i=1;i<=m;i++){if(g[i].q==0){int f1=g[i].f[1],f2=g[i].f[2];for(int j=n;j>=g[i].v;j--){if(f1&&j-g[f1].v-g[i].v>=0)f[j]=max(f[j],f[j-g[i].v-g[f1].v]+g[i].w+g[f1].w);if(f2&&j-g[f2].v-g[i].v>=0)f[j]=max(f[j],f[j-g[i].v-g[f2].v]+g[i].w+g[f2].w);if(f1&&f2&&j-g[i].v-g[f1].v-g[f2].v>=0)f[j]=max(f[j],f[j-g[i].v-g[f1].v-g[f2].v]+g[i].w+g[f1].w+g[f2].w);f[j]=max(f[j],f[j-g[i].v]+g[i].w);}}}printf("%d\n",f[n]);return 0;
}

依赖性背包

7)01背包求方案数

#include<iostream>
#include<cstdio>
using namespace std;
int f[10000],n,m,a[110];
int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&a[i]);f[0]=1;for(int i=1;i<=n;i++)for(int j=m;j>=a[i];j--)f[j]+=f[j-a[i]];printf("%d",f[m]);
}

01背包求方案数

三、区间型dp

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int w[101],f[101][101],sum[101];
int n;
int main() {scanf("%d",&n);for(int i=1; i<=n; i++) {scanf("%d",&w[i]);sum[i]=sum[i-1]+w[i];}for(int i=2; i<=n; i++)for(int j=i-1; j>=1; j--) {f[j][i]=0x3f3f3f3f;for(int k=j; k<i; k++)f[j][i]=min(f[j][i],f[j][k]+f[k+1][i]+sum[i]-sum[j-1]);}printf("%d\n",f[1][n]);return 0;
}

合并果子

四、概率dp

#include<iostream>
#include<cstdio>
using namespace std;
int n;
double dp[1280][1280];
int main(){scanf("%d",&n);n/=2;for(int i=2;i<=n;i++)dp[i][0]=dp[0][i]=1.0;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++) dp[i][j]=(dp[i-1][j]+dp[i][j-1])/2.0;printf("%.4lf\n",dp[n][n]);return 0;
}

搞笑世界杯

五、多维dp

#include<iostream>
#include<cstdio>
using namespace std;
int n,m,x,maxx,s[5],qp[355],f[40][40][40][40];
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&qp[i]);for(int i=1;i<=m;i++){scanf("%d",&x);if(x==1)s[1]++;if(x==2)s[2]++;if(x==3)s[3]++;if(x==4)s[4]++;}f[0][0][0][0]=qp[1];f[1][0][0][0]=qp[2];f[0][1][0][0]=qp[3];f[0][0][1][0]=qp[4];f[0][0][0][1]=qp[5];for(int i=0;i<=s[1];i++)for(int j=0;j<=s[2];j++)for(int l=0;l<=s[3];l++)for(int k=0;k<=s[4];k++){maxx=0;if(i)maxx=max(maxx,f[i-1][j][l][k]);if(j)maxx=max(maxx,f[i][j-1][l][k]);if(l)maxx=max(maxx,f[i][j][l-1][k]);if(k)maxx=max(maxx,f[i][j][l][k-1]);f[i][j][l][k]=maxx+qp[i+j*2+l*3+k*4+1];} printf("%d\n",f[s[1]][s[2]][s[3]][s[4]]);return 0;
}

乌龟棋

整理的不全,noip不会考很难的吧。【逃

转载于:https://www.cnblogs.com/zzyh/p/7806263.html

【经典】Noip动态规划相关推荐

  1. 13.最为经典的动态规划入门

    一.动态规划的简介 动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法. 动态规划背后的基本思想非常简单.大致上,若要解一个给定问题,我们需要解其不同部分(即 ...

  2. 几个经典的动态规划算法

    一.动态规划基本思想 一般来说,只要问题可以划分成规模更小的子问题,并且原问题的最优解中包含了子问题的最优解,则可以考虑用动态规划解决.动态规划的实质是分治思想和解决冗余,因此,动态规划是一种将问题实 ...

  3. 五大经典算法-动态规划 及其算法应用

    前言 整篇文章分析整个动态规划算法,什么是动态规划,及动态规划算法在字符串匹配中使用.分治法的差别点.动态规划优点: 概念 什么叫做动态规划(dynamic programming),它是运筹学的一个 ...

  4. JZOJ 3418. 【NOIP动态规划专题】选课

    Description 大学里实行学分.每门课程都有一定的学分,学生只要选修了这门课,并通过考核就能获得相应的学分.学生最后的学分是他各门课学分的总和.每个学生都要选择规定数量的课程.其中有些课程可以 ...

  5. 经典动态规划————背包九讲

    前言 本篇文章是我(dd_engi)正在进行中的一个雄心勃勃的写作计划的一部分,这个计划的内容是写作一份较为完善的NOIP难度的动态规划总结,名为<解动态规划题的基本思考方式>.现在你看到 ...

  6. c++ 多重背包状态转移方程_动态规划入门——详解经典问题零一背包

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是周三算法与数据结构专题的第12篇文章,动态规划之零一背包问题. 在之前的文章当中,我们一起探讨了二分.贪心.排序和搜索算法,今天我们来 ...

  7. 五大经典算法(贪婪、动态规划、分治、回溯、分支限界法)及其联系和比较

    一.贪心法 贪心算法的含义: 贪心算法(也叫贪婪算法)是指在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解.贪心算法不是对所有问题都能得 ...

  8. 动态规划入门——详解经典问题零一背包

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是周三算法与数据结构专题的第12篇文章,动态规划之零一背包问题. 在之前的文章当中,我们一起探讨了二分.贪心.排序和搜索算法,今天我们来 ...

  9. 动态规划经典题目总结

    微信公众号 在算法中,动态规划题目算是比较经典的一类题目.在找工作中,不管是笔试,还是面试,我们经常会遇到用动态规划来解决问题的情况,有时候面试官还需要我们现场手写出动态规划解法的代码.因此,在求职中 ...

最新文章

  1. ComboBox自动补全小技巧
  2. 李宏毅机器学习(二)自注意力机制
  3. 29 | 如何判断一个数据库是不是出问题了?
  4. 做网管这么久了,每个月只是拿1000元的工资
  5. MTK PerfService介绍
  6. 开关造成的毛刺_干冰清洗机模具清洗机干冰去毛刺机注意事项
  7. 默认大小_如何更改 Linux 控制台字体类型和大小 | Linux 中国
  8. matplotlib可视化学习笔记
  9. 移动计算的未来:是什么在推动变革? | 幂集创新
  10. Linux转发性能评估与优化 转发瓶颈分析与解决方案
  11. 12000字解读元气森林:套利与降维的游戏
  12. Java学习篇之I/O篇
  13. 设计师的色彩搭配指南
  14. 快速理解三角函数:积化和差、和差化积
  15. 线性电路特性的研究与multisim仿真(附工程文件)
  16. 为了理想,因为爱情-开课第一天有感(鸡汤向)
  17. 关于数据清洗的常见方式
  18. Hdu 5172 GTY's gay friends
  19. Python —— Numpy数组组合
  20. 一系列令人敬畏的.NET核心库,工具,框架和软件

热门文章

  1. python程序运行结果始终为0_Python:始终运行程序
  2. R语言实现混频数据分析
  3. 话题:什么是前端工程化?
  4. php 什么cms能让会员自已建个独立站并绑上二级域名?,CMS_帝国CMS使用二级域名并解决顶一下的方法,1、将2级域名解析指向到所在 - phpStudy...
  5. 根目录_ubuntu 18.04 server版根目录只有4G?
  6. gsea富集分析结果怎么看_简单的GSEA分析
  7. ocx控件 postmessage消息会消失_通过HackerOne漏洞报告学习PostMessage漏洞实战场景中的利用与绕过...
  8. Oracle完全手册,Oracle_11g+Oracle Sqldeveloper 安装完全手册(for win 7 64x)
  9. SpringBoot中模板引擎thymeleaf
  10. Spring中IoC创建对象方式(构造器注入)