1. 程式人生 > >「一本通 5.1 練習 2」分離與合體 題解

「一本通 5.1 練習 2」分離與合體 題解

-s color tps oid loj i++ code algo 練習

題目鏈接:這道題...

成功被卡題面。

真的卡題面....

我用了兩種方法(區間DP和記憶化搜索),這裏直接貼代碼了。

區間DP:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#define R register
#define ll long long int
using namespace std;
const int N=1005
; int n,a[N],f[N][N];//到第 i 個 劃分了 j 個區間 int main(){ scanf("%d",&n); for(R int i=1;i<=n;i++) scanf("%d",&a[i]); for(R int l=2;l<=n;l++) for(R int i=1;(i+l-1)<=n;i++){ R int j=i+l-1; for(R int k=i;k<j;k++) f[i][j]=max(f[i][j],(a[i]+a[j])*a[k]+f[i][k]+f[k+1
][j]); } printf("%d\n",f[1][n]); queue<int>q1,q2; q1.push(1); q2.push(n); while(!q1.empty()){ R int l=q1.front(),r=q2.front(); q1.pop();q2.pop(); for(R int k=l;k<r;++k){ if(f[l][r]==((a[l]+a[r])*a[k]+f[l][k]+f[k+1][r])){ printf(
"%d ",k); q1.push(l);q2.push(k); q1.push(k+1);q2.push(r); break; } } } return 0; }

記憶化搜索

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#define R register
#define ll long long int
using namespace std;
const int N=1005;
int n,a[N],f[N][N];//到第 i 個 劃分了 j  個區間
void dfs(R int l,R int r){
    if(f[l][r])return;
    for(R int k=l;k<r;k++){
        dfs(l,k);
        dfs(k+1,r);
        f[l][r]=max(f[l][r],f[l][k]+f[k+1][r]+(a[l]+a[r])*a[k]);
    }
}
int main(){
    scanf("%d",&n);
    for(R int i=1;i<=n;i++)
    scanf("%d",&a[i]);
    dfs(1,n);
    printf("%d\n",f[1][n]);
    queue<int>q1,q2;
    q1.push(1);
    q2.push(n);
    while(!q1.empty()){
       R int l=q1.front(),r=q2.front();
       q1.pop();q2.pop();
         for(R int k=l;k<r;++k){
        if(f[l][r]==((a[l]+a[r])*a[k]+f[l][k]+f[k+1][r])){
        printf("%d ",k);
        q1.push(l);q2.push(k);
         q1.push(k+1);q2.push(r);
         break;
        }
        }
    }
    return 0;
}

「一本通 5.1 練習 2」分離與合體 題解