「一本通 5.1 练习 2」分离与合体 题解

题目链接:这道题...

成功被卡题面。

真的卡题面....

我用了两种方法(区间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;
}

猜你喜欢

转载自www.cnblogs.com/sky-zxz/p/9858939.html