【经典】Noip动态规划
一、线性动态规划
最长严格上升子序列
- #include<iostream>
- #include<cstdio>
- using namespace std;
- int n,ans;
- int a[],dp[];
- int main()
- {
- scanf("%d",&n);
- for(int i=;i<=n;i++)
- scanf("%d",&a[i]);
- for(int i=;i<=n;i++)
- {
- for(int j=;j<i;j++)
- {
- if(a[j]<a[i])
- dp[i]=max(dp[i],dp[j]+);
- ans=max(ans,dp[i]);
- }
- }
- printf("%d\n",ans+);
- return ;
- }
最长严格上升子序列
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- const int maxn=0x3f3f3f3f;
- int n,a[],dp[];
- int main()
- {
- scanf("%d",&n);
- for(int i=;i<=n;i++)
- scanf("%d",&a[i]);
- memset(dp,0x3f,sizeof(dp));
- for(int i=;i<=n;i++)
- {
- int p=upper_bound(dp+,dp+n+,a[i])-dp;
- if(a[i]!=dp[p-])//严格上升序列
- dp[p]=a[i];
- }
- for(int i=;i<=n+;i++)
- {
- if(dp[i]==maxn)
- {
- printf("%d\n",i-);
- return ;
- }
- }
- return ;
- }
nlogn
变形:打鼹鼠
- #include<iostream>
- #include<cstdlib>
- #include<cstdio>
- using namespace std;
- int maxt,n,m,ans,x[],y[],t[],f[];
- int main()
- {
- int i,j;
- scanf("%d%d",&n,&m);
- for (i=;i<=m;++i)
- scanf("%d%d%d",&t[i],&x[i],&y[i]);
- for (i=;i<=m;++i)
- {
- f[i]=;//f表示到第i只鼹鼠出现时最多可以打到多少只
- for (j=i-;j>=;--j)
- if (t[i]-t[j]>=abs(x[i]-x[j])+abs(y[i]-y[j]))
- //如果时间足够,能从j点移动到当前点
- f[i]=max(f[i],f[j]+);
- ans=max(ans,f[i]);
- }
- printf("%d",ans);
- }
Luogu打鼹鼠
二、背包
1)01背包
每个物品只有一个且只有选与不选两种可能
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- using namespace std;
- int f[],w[],v[];
- int n,m,t;
- int main()
- {
- scanf("%d",&t);
- while(t--)
- {
- memset(f,,sizeof(f));
- scanf("%d%d",&n,&m);
- for(int i=;i<=n;i++)
- scanf("%d",&v[i]);
- for(int i=;i<=n;i++)
- scanf("%d",&w[i]);
- for(int i=;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 ;
- }
01背包
2)完全背包
每件物品数量无限
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- using namespace std;
- int w1,w2,wi,t,k,f[],v[],w[];
- int main()
- {
- scanf("%d",&t);
- while(t--)
- {
- memset(f,0x3f,sizeof(f));
- f[]=; //**
- scanf("%d%d",&w1,&w2);
- wi=w2-w1;
- scanf("%d",&k);
- for(int i=;i<=k;i++)
- scanf("%d%d",&v[i],&w[i]);
- for(int i=;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");
- else
- printf("The minimum amount of money in the piggy-bank is %d.\n",f[wi]);
- }
- return ;
- }
完全背包
3)多重背包
每个物品数量一定
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- using namespace std;
- int t,mon,k,w[],pri[],f[],cnt[];
- int main()
- {
- scanf("%d",&t);
- while(t--)
- {
- memset(f,,sizeof(f));
- scanf("%d%d",&mon,&k);
- for(int i=;i<=k;i++)
- scanf("%d%d%d",&pri[i],&w[i],&cnt[i]);
- for(int i=;i<=k;i++)
- {
- for(int j=mon;j>=pri[i];j--)
- {
- for(int h=;h<=cnt[i];h++)
- {
- if(j-h*pri[i]<)break;
- f[j]=max(f[j],f[j-h*pri[i]]+h*w[i]);
- }
- }
- }
- printf("%d\n",f[mon]);
- }
- return ;
- }
多重背包
4)混合背包
-1为无限个
- #include<iostream>
- #include<cstdio>
- #include<cstdlib>
- using namespace std;
- int w[],v[],c[],dp[];
- int main()
- {
- int vv,n;
- scanf("%d%d",&n,&vv);
- for(int i=;i<=n;i++)
- scanf("%d%d%d",&w[i],&v[i],&c[i]);
- for(int i=;i<=n;i++)
- {
- if(c[i]==-)
- {
- 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=;j<=x;j<<=)
- {
- 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!=)
- {
- 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 ;
- }
混合背包
5)二维费用背包
- #include<bits/stdc++.h>
- using namespace std;
- int f[][];
- int main(){
- int n,m,x;
- cin>>n>>m>>x;
- for(int i=;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 ;
- }
二维费用
6)有依赖性背包问题
- #include<iostream>
- #include<cstdio>
- using namespace std;
- struct e
- {
- int v,p,q,w,f[];
- }g[];
- int n,m,f[];
- int main()
- {
- scanf("%d%d",&n,&m);
- for(int i=;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!=)
- g[g[i].q].f[++g[g[i].q].f[]]=i;
- }
- for(int i=;i<=m;i++)
- {
- if(g[i].q==)
- {
- int f1=g[i].f[],f2=g[i].f[];
- for(int j=n;j>=g[i].v;j--)
- {
- if(f1&&j-g[f1].v-g[i].v>=)
- 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>=)
- 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>=)
- 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 ;
- }
依赖性背包
7)01背包求方案数
- #include<iostream>
- #include<cstdio>
- using namespace std;
- int f[],n,m,a[];
- int main(){
- scanf("%d%d",&n,&m);
- for(int i=;i<=n;i++)scanf("%d",&a[i]);
- f[]=;
- for(int i=;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[],f[][],sum[];
- int n;
- int main() {
- scanf("%d",&n);
- for(int i=; i<=n; i++) {
- scanf("%d",&w[i]);
- sum[i]=sum[i-]+w[i];
- }
- for(int i=; i<=n; i++)
- for(int j=i-; j>=; j--) {
- f[j][i]=0x3f3f3f3f;
- for(int k=j; k<i; k++)
- f[j][i]=min(f[j][i],f[j][k]+f[k+][i]+sum[i]-sum[j-]);
- }
- printf("%d\n",f[][n]);
- return ;
- }
合并果子
四、概率dp
- #include<iostream>
- #include<cstdio>
- using namespace std;
- int n;
- double dp[][];
- int main(){
- scanf("%d",&n);n/=;
- for(int i=;i<=n;i++)dp[i][]=dp[][i]=1.0;
- for(int i=;i<=n;i++)
- for(int j=;j<=n;j++)
- dp[i][j]=(dp[i-][j]+dp[i][j-])/2.0;
- printf("%.4lf\n",dp[n][n]);
- return ;
- }
搞笑世界杯
五、多维dp
- #include<iostream>
- #include<cstdio>
- using namespace std;
- int n,m,x,maxx,s[],qp[],f[][][][];
- int main()
- {
- scanf("%d%d",&n,&m);
- for(int i=;i<=n;i++)
- scanf("%d",&qp[i]);
- for(int i=;i<=m;i++)
- {
- scanf("%d",&x);
- if(x==)s[]++;
- if(x==)s[]++;
- if(x==)s[]++;
- if(x==)s[]++;
- }
- f[][][][]=qp[];
- f[][][][]=qp[];
- f[][][][]=qp[];
- f[][][][]=qp[];
- f[][][][]=qp[];
- for(int i=;i<=s[];i++)
- for(int j=;j<=s[];j++)
- for(int l=;l<=s[];l++)
- for(int k=;k<=s[];k++)
- {
- maxx=;
- if(i)maxx=max(maxx,f[i-][j][l][k]);
- if(j)maxx=max(maxx,f[i][j-][l][k]);
- if(l)maxx=max(maxx,f[i][j][l-][k]);
- if(k)maxx=max(maxx,f[i][j][l][k-]);
- f[i][j][l][k]=maxx+qp[i+j*+l*+k*+];
- }
- printf("%d\n",f[s[]][s[]][s[]][s[]]);
- return ;
- }
乌龟棋
整理的不全,noip不会考很难的吧。【逃
【经典】Noip动态规划的更多相关文章
- [题解+总结]NOIP动态规划大合集
1.前言 NOIP2003-2014动态规划题目大合集,有简单的也有难的(对于我这种动态规划盲当然存在难的),今天就把这些东西归纳一下,做一个比较全面的总结,方便对动态规划有一个更深的理解. 2.NO ...
- NOIP动态规划大合集
1.前言 NOIP2003-2014动态规划题目大合集,有简单的也有难的(对于我这种动态规划盲当然存在难的),今天就把这些东西归纳一下,做一个比较全面的总结,方便对动态规划有一个更深的理解. 2.NO ...
- POJ1088滑雪(记忆化搜索+DFS||经典的动态规划)
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 84297 Accepted: 31558 Description M ...
- Edit Distance——经典的动态规划问题
题目描述Edit DistanceGiven two words word1 and word2, find the minimum number of steps required to conve ...
- NOIP 2010题解
唔..NOIP2010比较简单,总体感觉不错. Problem 1: 机器翻译 水题,队列的简单应用. 读入时判断是否在内存中,可以用hash优化.如果不在内存中push进内存,放不下了pop hea ...
- hdu 2084 数塔(动态规划)
本题是一个经典的动态规划题. 直接利用记忆化搜索:见图解 Ac code : #include<stdio.h> #include<string.h> #define max( ...
- hdu 1159 Palindrome(回文串) 动态规划
题意:输入一个字符串,至少插入几个字符可以变成回文串(左右对称的字符串) 分析:f[x][y]代表x与y个字符间至少插入f[x][y]个字符可以变成回文串,可以利用动态规划的思想,求解 状态转化方程: ...
- [LeetCode] 动态规划入门题目
最近接触了动态规划这个厉害的方法,还在慢慢地试着去了解这种思想,因此就在LeetCode上面找了几道比较简单的题目练了练手. 首先,动态规划是什么呢?很多人认为把它称作一种"算法" ...
- UVA1627-Team them up!(动态规划)
Problem UVA1627-Team them up! Total Submissions:3577 Solved:648 Time Limit: 3000 mSec Problem Descr ...
随机推荐
- 安装配置zabbix代理之zabbix_proxy
配置Proxy代理 如图所示: zabbix_server端在阿里云上,其代理程序部署在各地机房,代理程序收集所在机房的所有机器监控指标,然后传给server端 环境说明: CentOS releas ...
- Windows 修改个性化时间显示
A goal is a dream with a deadline. Much effort, much prosperity. 我感觉我的时间显示不够人性化.不够个性化 修改注册表 我的系统为Win ...
- JMS-activMq与spring进行整合
对JMS做了一个简要介绍之后,接下来就讲一下Spring整合JMS的具体过程.JMS只是一个标准,真正在使用它的时候我们需要有它的具体实现,这里我们就使用Apache的activeMQ来作为它的实现 ...
- HTTP Status 500 - java.lang.NoClassDefFoundError: JspTagException
HTTP Status 500 - java.lang.NoClassDefFoundError: JspTagException cause java.lang.NoClassDefFoundEr ...
- LeetCode第[15]题(Java):3Sum (三数之和为目标值)——Medium
题目难度:Medium 题目: Given an array S of n integers, are there elements a, b, c in S such that a + b + c ...
- Django开发点菜系统学习笔记
1.使用django-simple-captcha包的时候,会调用到: register_form = RegisterForm(request.POST) 但是这个时候captcha不进行错误检验, ...
- maven setting仓库镜像
国内连接maven官方的仓库更新依赖库,网速一般很慢,收集一些国内快速的maven仓库镜像以备用. 最新更新:2016年11月11日 18:05:40 阿里云提供Maven私服,我把配置文件贴一下,自 ...
- 【转】安装OS X虚拟机错误vcpu-0:VERIFY vmcore/vmm/main/physMem_monitor.c:1123
新建一个虚拟机, 选择客户机操作系统为Apple MacOS X 10.10, 其余参数可以默认. 注意建好之后不要急着打开客户机, 因为直接打开你会发现新建的客户机将会无法启动. 仔细阅读Mac O ...
- python面向对象编程 继承 组合 接口和抽象类
1.类是用来描述某一类的事物,类的对象就是这一类事物中的一个个体.是事物就要有属性,属性分为 1:数据属性:就是变量 2:函数属性:就是函数,在面向对象里通常称为方法 注意:类和对象均用点来访问自己的 ...
- opencv:基本图形绘制
可以使用opencv绘制 直线.圆.方形.椭圆等基本图形. 示例代码: #include <opencv.hpp> using namespace cv; int main() { // ...