「一本通 5.1 练习 2」分离与合体 题解
Posted sky-zxz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「一本通 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 ",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 ",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」分离与合体 题解的主要内容,如果未能解决你的问题,请参考以下文章