acm DP经典5题
来源:互联网 发布:歌曲伴奏制作软件下载 编辑:程序博客网 时间:2024/06/06 05:29
1.最大连续子序列
给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序中元素和最大的一个, 例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和为20。
状态转移方程:dp[i]=max(dp[i-1]+a[i],a[i]);
#include<iostream>#include<cstdio>#include<cstring>#include<ctime>#include<algorithm>#include <map>#include <set>using namespace std;//2015.4.1//最大连续子序列 假设100个数typedef long long LL;int dp[100];int a[100];int n;int main(){ while(true) { memset(dp,0,sizeof(dp)); cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; } dp[1]=a[1]; for(int i=2;i<=n;i++) { dp[i]=max(dp[i-1]+a[i],a[i]); } printf("%d\n",dp[n]); } return 0;}
2.数塔问题
数塔问题 :要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?
状态转移方程:dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+a[i][j];
#include<iostream>#include<cstdio>#include<cstring>#include<ctime>#include<algorithm>#include <map>#include <set>using namespace std;//2015.4.1//数塔typedef long long LL;int n;int dp[100][100];int a[100][100];int main(){ while(true) { cin>>n; int key=1; for(int i=1;i<=n;i++) { for(int j=1;j<=i;j++) { cin>>a[i][j]; if(i==n) { dp[i][j]=a[i][j]; } } for(int i=n-1;i>=1;i--) { for(int j=1;j<=i;j++) { dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+a[i][j]; } } } cout<<dp[1][1]<<endl; } return 0;}
3.背包问题
有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
状态转移方程:dp[i][j]=max(dp[i-1][j],dp[i][j-w[i]]+c[i]);
#include<iostream>#include<cstdio>#include<cstring>#include<ctime>#include<algorithm>#include <map>#include <set>using namespace std;//2015.4.1//背包问题int c[100],w[100];int dp[100][100];//前i个物品中选j重int n,v;int main(){ while(true) { memset(dp,0,sizeof(dp)); cin>>n>>v; for(int i=1;i<=n;i++) { cin>>c[i]>>w[i]; } for(int i=1;i<=n;i++) { for(int j=1;j<=v;j++) { dp[i][j]=max(dp[i-1][j],dp[i][j-w[i]]+c[i]); } } cout<<dp[n][v]<<endl; } return 0;}
4.最长递增子序列
给定一个序列 An = a1 ,a2 , ... , an ,找出最长的子序列使得对所有 i < j ,ai < aj 。
状态转移方程:i>j if(a[i]>a[j]) dp[i]=dp[j]+1
#include<iostream>#include<cstdio>#include<cstring>#include<ctime>#include<algorithm>#include <map>#include <set>using namespace std;//2015.4.1//最长递增子序列int f[100];int a[100];int n;int ans;int main(){ while(true) { cin>>n; ans=1; for(int i=1;i<=n;i++) { cin>>a[i]; f[i]=1; } for(int i=2;i<=n;i++) { for(int j=i-1;j>=1;j--) { if(a[i]>a[j]&&f[i]<=f[j]) { f[i]=f[j]+1; if(f[i]>ans)ans=f[i]; } } } cout<<ans<<endl; } return 0;}
5.最长公共子序列一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。
这个题似乎常用来检测是否一篇文章时抄袭的。
状态转移方程:if(a[i]==b[j])dp[i][j]=dp[i-1][j-1]+1
else if(a[i]!=a[j]) dp[i][j]=dp[i-1][j-1]
if(i==0||j==0)dp[i][j]=0
#include<iostream>#include<cstdio>#include<cstring>#include<ctime>#include<algorithm>#include <map>#include <set>using namespace std;//2015.4.1//最长公共子序列int dp[100][100];int a[100];int b[100];int n,m;int main(){ while(true) { cin>>n>>m; for(int i=1;i<=n;i++) { cin>>a[i]; dp[i][0]=0; } for(int j=1;j<=m;j++) { cin>>b[j]; dp[0][j]=0; } dp[0][0]=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(a[i]==b[j]) { dp[i][j]=dp[i-1][j-1]+1; } else if(dp[i][j-1]>=dp[i-1][j]) { dp[i][j]=dp[i][j-1]; } else { dp[i][j]=dp[i-1][j]; } } } cout<<dp[n][m]<<endl; } return 0;}
0 0
- acm DP经典5题
- DP经典5题 【DP】
- DP经典5题
- DP经典5题
- acm经典题Mark
- ACM-经典DP之Monkey and Banana——hdu1069
- [ACM] HDU 1227 Fast Food (经典Dp)
- 树形DP经典题
- poj1952(经典dp题)
- DP经典题
- PKU ACM经典50题
- PKU ACM经典50题
- PKU ACM经典50题
- ***UVa-1626 Brackets sequence ACM解题报告(巧妙地递推+打印)经典的括号 dp题
- acm DP经典题目 滑雪问题 【DP 记忆化搜索 递归】
- 区间dp经典三题
- 贪心+dp--hdu5501(经典题)
- 经典DP
- mac os x 10.10.2 wifi下 safari 无法打开网页
- hibernat之一级缓存的原理
- android开发 - 现场保存
- TopCoder SRM 654 Div2 Problem 500 - OneEntrance (思维)
- Android组件及UI框架大全
- acm DP经典5题
- ListView具有多种item布局——实现微信对话列
- android开发 - Broadcast Receiver
- 并查集解题报告
- SpringMVC 概述
- 作业3.23
- 小白鼠与毒药解题过程分析
- android开发 - APK签名
- windows下NDK环境搭建 简单搭建NDK环境