hdu 4570 Multi-bit Trie 【区间dp】

来源:互联网 发布:ubuntu l2tp 编辑:程序博客网 时间:2024/05/19 22:04


点击打开链接


题意难度太高,后来问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 longusing 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;}


原创粉丝点击