算法學習——動態規劃常見例題及實現程序

題目來源於此大神: 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
--------------------- 
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章