紫書第九章-----動態規劃初步(數字三角形)
阿新 • • 發佈:2019-02-01
本文參考劉汝佳《演算法競賽入門經典》(第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;
}