【经典】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 ...
随机推荐
- UEFI引导修复
一.用bcbboot自动修复 我们建议大家启动64位8PE,用它带的bcdboot来修复. (一)指定esp分区修复 环境为64位8PE,bios/uefi启动进入下都可以 1.启动64位8PE,并用 ...
- jQuery单选多选按钮选中美化特效
在线演示 本地下载
- mysql 5.7快速部署
目录 一:官网下载mysql二级制包.... 1 二:mysql二级制包解压.... 1 三:设置mysql库文件路径与授权... 1 四. 创建配置文件... 2 五:数据库初始化... 5 六: ...
- Windows 10 调节缩略图背景透明度
A goal is a dream with a deadline. Much effort, much prosperity. 用Windows 10 的朋友都知道 win10 确实挺好用,但是做的 ...
- spring security结合数据库验证用户-注解方式
项目目录结构如下: 首先数据库的建立和数据导入,以及一些类的依赖参考XML配置方式,需要修改一些配置. 一.在AppConfig文件中添加DataSource的配置 @Bean(name = &quo ...
- 第三篇:Spark SQL Catalyst源码分析之Analyzer
/** Spark SQL源码分析系列文章*/ 前面几篇文章讲解了Spark SQL的核心执行流程和Spark SQL的Catalyst框架的Sql Parser是怎样接受用户输入sql,经过解析生成 ...
- 多线程-模拟阻塞queue队列
前阵子学习了多线程,现在进行总结一下,模拟队列. 分析问题: (1)首先需要一个容器存放元素,这里用linkedList队列. (2)每次像容器中添加或删除元素的时候需要计数,所以这里需要一个计数器, ...
- JDK_环境变量
1. 在系统环境变量中设置: ClASSPATH中输入: ".;C:\Program Files\Java\jdk1.7.0_07\jre\lib\rt.jar;"//java的安 ...
- Android 通过名称获取资源ID
当我们获取网络数据的时候,解析之后往往都是一个字符串,而不是资源id,所有我们没有办法直接使用,只能通过名称来获取到资源id, package com.example.administrator.de ...
- ubuntu16.04 运行elasticfusion
环境:Ubuntu16.04 64bit Kinect V1 XBOX 360 1.安装OpenNI2并试运行 https://fredfire1.wordpress.com/2016/09/2 ...