当时现场赛看不懂。。。
最近几天偶然又看到这题了。。。边查字典边看发现就是一道水题。。。
dp[i] 表示从第i个level往后扩展所需要的最少table数,然后转移是dp[i] = min(dp[i],dp[j]+s[i]*2^(j-i)); j = i+1,i+2,i+3.....,i+20
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
typedef long long LL;
LL s[65],dp[65];
int n;
LL dfs(int level){
if(level==n) return 0;
if(~dp[level]) return dp[level];
dp[level] = (1ll<<62)-1;
for(int i = level+1;i<=min(level+20,n);i++){
dp[level] = min(dp[level],dfs(i)+s[level]*(1<<(i-level)));
}
return dp[level];
}
int main(void){
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
long long ans = 0;
for(int i = 0;i<n;i++) scanf("%I64d",&s[i]),ans+=s[i]*2;
memset(dp,-1,sizeof(dp));
printf("%I64d\n",min(ans,dfs(0)));
}
}