1570:【例 2】能量项链

思路:

很简单的区间dp,注意最外层循环设置成(当前合并区间长度)和(当前合并次数)之间的差异

代码:(当前合并的区间长度)

```cpp #include #define ll long long #define maxn 2050

using namespace std;

struct node{
ll l,r;
}a[maxn];
ll f[maxn][maxn],n;
//2 3 5 10 2 3 5 10
int main()
{
memset(f,0,sizeof(f));
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].l ;
a[i-1].r =a[i].l ;
a[i+n].l =a[i].l ;
a[i+n-1].r =a[i].l ;
}

a[2*n].r =a[1].l ;

// for(int i=1;i<=2n;i++) cout<<a[i].l <<" "<<a[i].r <<' ';
for(int l=2;l<=n;l++)//枚举区间长度
{
for(int i=1;i+l-1<=2
n;i++)
{
int j=i+l-1;
for(int k=i;k<j;k++)
{
f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+a[i].l*a[k].r *a[j].r);
// cout<<i<<" "<<j<<" "<<k<<" "<<f[i][j]<<" "<<f[i][k]<<" "<<f[k+1][j]<<" "<<a[k].l <<" "<<a[k].r <<" "<<a[k+1].r <<' ';
}
}
}

ll ans=0;
/*
for(int i=1;i<=2*n;i++)
{

	for(int j=1;j<=2*n;j++)
	{
		cout<<f[i][j]<<" ";
	}
	cout<<'
';
}*/

for(int i=1;i<=n;i++)
{
	ans=max(ans,f[i][i+n-1]);
 } 
 
 cout<<ans<<'
';
 return 0;

}


(当前合并次数):
```cpp
#include <cstdio> 
#include <cstring> 
#include <iostream> 
using namespace std; 
int f[210][210]; 
struct node 
{ 
    int x,y; //头标记和尾标记
}a[210]; 
int main() 
{ 
    int n; 
    scanf("%d",&n); 
    for (int i=1;i<=n;i++) 
    { 
        scanf("%d",&a[i].x); 
        a[i-1].y=a[i].x; //前一个珠子的尾标记等于后一个珠子的头标记
    } 
    a[n].y=a[1].x; //注意是环!收尾相连
    for (int i=1;i<n;i++) 
        a[i+n]=a[i]; //复制一段在后边,那么从i~i+n就是看成是一个从i开始的一条线了,省了一条循环
    memset(f,0,sizeof(f)); //赋0
    //f[i][j]:合并第i~j个珠子时的最优情况
    for (int k=1;k<=n;k++) //枚举长度(与合并石子的x相似)
    { 
        for (int i=1;i<2*n-k;i++) //从第i个石子开始断,,那么从i~i+n就是一条线
        { 
            for (int j=i;j<i+k;j++) //在i~i+k中选一个点j分成i~j和j+1~i+k两段(与合并石子的k相同)
            { 
                f[i][i+k]=max(f[i][i+k],f[i][j]+f[j+1][i+k]+a[i].x*a[j].y*a[i+k].y); //计算能量
            } 
        } 
    } 
    int ans=0; 
    for (int i=1;i<=n;i++) 
    { 
        ans=max(f[i][i+n-1],ans); 
        //扫一遍,看看从哪里断得到的值最大
    } 
    
    for(int i=1;i<=2*n;i++)
    {
    	for(int j=1;j<=2*n;j++) cout<<f[i][j]<<" ";
		cout<<'
'; 
	}
    printf("%d",ans); 
    return 0; 
} 

原文地址:https://www.cnblogs.com/yxr001002/p/14445075.html