題目來源於此大神: http://blog.csdn.net/tobewhatyouwanttobe/article/details/42805225
我是按照該blog來入門dp相關問題的。不斷更新中。。。。。。2019/2/25
一、數塔問題
具體描述見連接:http://acm.hdu.edu.cn/showproblem.php?pid=2084
#include <stdio.h>
int main(){
int N;
int num;
scanf("%d",&N);
for(int i=0;i<N;i++){
scanf("%d",&num);
int *matrix = new int[num*(num+1)/2+1];
int tmp;
int cnt = 1;
for(int j = 0;j<num*(num+1)/2+1;j++)
matrix[j]=0;
for(int j = 0;j<num;j++){
if(j==0){
scanf("%d",&tmp);
matrix[0] = tmp;
continue;
} //對於第一個值直接使用
for(int k = 0;k<=j;k++){
scanf("%d",&tmp);
if(k==0) matrix[cnt] = matrix[cnt-j] +tmp;
else if(k==j)
matrix[cnt] = matrix[cnt-j-1] +tmp; // 邊界值只加上一個邊界值
else{
int max1 = tmp + matrix[cnt-j-1];
int max2 = tmp + matrix[cnt-j];
matrix[cnt] = max1>max2?max1:max2;
} //非邊界值取路徑相加最大的那個
cnt++;
}
}
int max = matrix[(--cnt)];
// printf("%d %d ",cnt,num);
for(int max_i = 1;max_i<num;max_i++){
max = max > matrix[cnt-max_i] ? max:matrix[cnt-max_i]; //獲得最大值
}
printf("%d\n",max);
}
return 0;
}
結果:Accepted
二、最長上升子序列
具體描述見連接:http://poj.org/problem?id=2533
// write your code here cpp
#include<stdio.h>
int main(){
int N;
while(scanf("%d",&N)!= EOF){
int *arr = new int[N];
int *martix = new int [N];
for(int i = 0;i<N;i++){
scanf("%d",&arr[i]);
martix[i] = 0;
}
for(int i = 1;i<N;i++){
for(int j = i-1;j>=0;j--)
if(arr[i] > arr[j])
martix[i] = martix[i] > (martix[j]+1)?martix[i]:(martix[j]+1);
}
int result = martix[0];
for(int k = 1;k<N;k++)
result = martix[k]>result?martix[k]:result;
printf("%d\n",result+1);
}
}
結果:Accepted
PS: 時間複雜度爲 o(N^2) 比較久
三、 hdu 1087 最大遞增和
具體描述見連接:http://acm.hdu.edu.cn/showproblem.php?pid=1087
// write your code here cpp
#include<stdio.h>
int main(){
int N;
while(scanf("%d",&N)!= EOF && N!=0){
int *arr = new int[N];
int *martix = new int [N];
for(int i = 0;i<N;i++){
scanf("%d",&arr[i]);
martix[i] = arr[i];
}
for(int i = 1;i<N;i++){
for(int j = i-1;j>=0;j--)
if(arr[i] > arr[j])
martix[i] = martix[i] > (martix[j]+arr[i])?martix[i]:(martix[j]+arr[i]);
}
int result = martix[0];
for(int k = 1;k<N;k++)
result = martix[k]>result?martix[k]:result;
printf("%d\n",result);
}
}
結果:Accepted
PS:其實這道題跟第二個問題很類似,將第二問題改一下就好。
四、 hdu 2602 01揹包
具體描述見連接:http://acm.hdu.edu.cn/showproblem.php?pid=2602
#include<stdio.h>
#include<math.h>
#include <cstring>
int MaxValue[1000][1000];
int main(){
int Case,N,V;
scanf("%d",&Case);
while(Case--){
scanf("%d%d",&N,&V);
int *Value = new int[N+1];
int *Volume = new int [N+1];
for(int i = 1;i<=N;i++){
scanf("%d",&Value[i]);
}
for(int i = 1;i<=N;i++){
scanf("%d",&Volume[i]);
}
memset(MaxValue,0,sizeof(MaxValue));
for(int i = 1;i<=N;i++)
for(int j = 0;j<=V;j++){
if(Volume[i]<=j)
MaxValue[i][j] = fmax(MaxValue[i-1][j],MaxValue[i-1][j-Volume[i]]+Value[i]);
else
MaxValue[i][j] = MaxValue[i-1][j];
//printf("%d ",MaxValue[i][j]);
}
printf("%d\n",MaxValue[N][V]);
delete[] Value;
delete[] Volume;
}
return 0;
}
一維滾動數組
#include<bits/stdc++.h>
using namespace std;
int dp[20001];
int main(){
int V,N;
scanf("%d%d",&V,&N);
int *tmp = new int[N];
for(int i =0;i<N;i++)
scanf("%d",&tmp[i]);
//edge
for(int i =0;i<=V;i++)
dp[i] =0;
for(int i = 1;i<=N;i++){
for(int v = V;v>=tmp[i];v--){
dp[v] = max(dp[v],dp[v-tmp[i]]+tmp[i]);
}
}
int maxV = 0;
for(int i =0;i<=V;i++)
maxV = max(maxV,dp[i]);
printf("%d\n",V-maxV);
return 0;
}
完全揹包問題:
五、 poj 1458 最長公共子序列
具體描述見連接:http://poj.org/problem?id=1458
#include <stdio.h>
#include <string>
#include <iostream>
#include <cmath>
using namespace std;
int maxvalue[1000][1000];
int main(){
string str1,str2;
while(cin >> str1 >> str2){
int len1 = str1.length(),len2 = str2.length();
for(int i = 0;i<len2;i++)
maxvalue[0][i] = 0;
for(int i = 0;i<len1;i++)
maxvalue[i][0] = 0;
for(int i = 1;i<=len1;i++)
for(int j = 1;j<=len2;j++){
if(str1[i-1]== str2[j-1])
maxvalue[i][j] = 1 + maxvalue[i-1][j-1];
else{
maxvalue[i][j] = fmax(maxvalue[i-1][j],maxvalue[i][j-1]);
}
}
cout << maxvalue[len1][len2]<< endl;
}
return 0;
}
六、神奇的口袋
#include <bits/stdc++.h>
using namespace std;
const int W = 40;
int main(){
int N;
scanf("%d",&N);
vector< vector<int>> way (W+1,vector<int>(N+1));
vector<int > arr(N+1);
for(int i = 1;i<=N;++i){
cin >>arr[i];
way[0][i] = 1;
}
way[0][0]=1;
for(int w =1;w<=W;++w){
for(int k =1;k<=N;k++){
way[w][k] =way[w][k-1];
int tmp = w-arr[k];
if( tmp>=0){
way[w][k] += way[tmp][k-1];
}
}
}
cout << way[W][N]<<endl;
return 0;
}
注:本博文爲原創,後續可能繼續更新本文。如果轉載,請務必複製本條信息!
原文地址:https://blog.csdn.net/aron_conli/article/details/87925453
原作者博客:https://blog.csdn.net/aron_conli
---------------------
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!