题意难度太高,后来问llm说大致是 给你n个数,然后让你随意划分成任意段区间(每一段最长为20),保证最后的区间和最小,
每一段区间值的算法是这样的,该区间值等于区间首字母*2^(区间长度);
题解:区间dp,
初始化: 长度最长为20,那么当 l<20时, dp[i][j]=a[i]*pow(2,l)*2;
when i>20: dp[i][j]=(sum[j]-sum[i-1])*2; 所有数字都是单个区间,没有合并。
之后遍历每个区间即可。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=105;
ll n,m,p,h,c;
ll a[maxn],sum[maxn];
ll dp[maxn][maxn];
ll Pow(int x){
ll ret=1;
for(int i=1;i<=x;++i) ret*=2;
return ret;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%lld",&n);
for(int i=1;i<=n;++i){
scanf("%lld",&a[i]);
sum[i]=sum[i-1]+a[i];
}
for(int l=0;l<=n;++l){
for(int i=1;i+l<=n;++i){
int j=i+l;
if(l<20) dp[i][j]=a[i]*Pow(l);
else dp[i][j]=sum[j]-sum[i-1];
for(int k=i;k<=j;++k){
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
}
}
}
printf("%lld\n",dp[1][n]*2);
}
return 0;
}