1. 程式人生 > >紫書第九章-----動態規劃初步(數字三角形)

紫書第九章-----動態規劃初步(數字三角形)

本文參考劉汝佳《演算法競賽入門經典》(第2版)

動態規劃的核心是狀態和狀態轉移方程

數字三角形 OpenJ_Bailian - 2760

這裡寫圖片描述
這裡寫圖片描述
【分析】

  • 狀態:d(i,j)表示從點(i,j)出發後能得到的最大和
  • 狀態轉移方程:d(i,j)=max(d(i+1,j),d(i+1,j+1))

方法1(遞迴計算Time Limit Exceeded)

#include<iostream>

using namespace std;

const int maxn=105;

int a[maxn][maxn]={0};
int n;

void read(){
    cin
>>n; for(int i=1;i<=n;i++){ for(int j=1;j<=i;j++){ cin>>a[i][j]; } } } int solve(int i,int j){ return a[i][j]+(i==n?0:max(solve(i+1,j),solve(i+1,j+1))); } int main() { read(); cout<<solve(1,1)<<endl; return 0; }

這裡寫圖片描述

方法2(遞推計算)

#include<iostream>

using namespace std;

const int maxn=105;

int a[maxn][maxn]={0};
int d[maxn][maxn];
int n;

void read(){
    cin>>n;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++){
            cin>>a[i][j];
        }
    }
}

void solve(){
   for(int i=1;i<=n;i++) d[n][i]=a[n][i];
   for
(int i=n-1;i>=1;i--){ for(int j=1;j<=i;j++){ d[i][j]=a[i][j]+max(d[i+1][j],d[i+1][j+1]); } } } int main() { read(); solve(); cout<<d[1][1]<<endl; return 0; }

這裡寫圖片描述

方法三(記憶化搜尋)

#include<iostream>
#include<cstring>
using namespace std;

const int maxn=105;

int a[maxn][maxn]={0};
int d[maxn][maxn];
int n;

void read(){

    cin>>n;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++){
            cin>>a[i][j];
        }
    }
}

int solve(int i,int j){
   if(d[i][j]>=0) return d[i][j];
   return d[i][j]=a[i][j]+(i==n?0:max(solve(i+1,j),solve(i+1,j+1)));
}

int main()
{
    memset(d,-1,sizeof(d));
    read();
    solve(1,1);
    cout<<d[1][1]<<endl;
    return 0;
}

這裡寫圖片描述