hdu 4570 Multi-bit Trie

8 篇文章 1 订阅
2 篇文章 1 订阅

原文链接
。。。这一题,,,花时间最多的是看题目。

题意(别处复制):
一个长度为n的数列,将其分成若干段(每一段的长度要<=20),
要求∑ai*(2^bi)最小,其中ai是每一段数列的第一项,bi是每一段的长度。

比如sample imput
n=7,A={1 2 4 4 5 4 3},将其分成1 2 4| 4 5| 4| 3,
则其所用空间为1*2^3+4*2^2+4*2^1+3*2^1=38,
而如果分成1 2| 4 4 5| 4 3,则其所用空间为1*2^2+4*2^3+4*2^2=52,比38大。

很明显区间dp。(区间dp一般思路

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
long long int dp[65][65];
long long int a[65];
long long int pow2[21];
long long int sum[65];
void init()
{
    pow2[0]=1;
    for(long long int i=1;i<=20;i++)
        pow2[i]=pow2[i-1]*2;
}
int main()
{
    long long int t,n;
    init();
    scanf("%I64d",&t);
    while(t--)
    {
        scanf("%I64d",&n);
        sum[0]=0;
        for(long long int i=0;i<n;i++)
        {
            scanf("%I64d",&a[i]);
            if(i>0)
            sum[i]=sum[i-1]+a[i];
            else
                sum[i]=a[i];
        }
        for(long long int p=1;p<=n;p++)
        {
            for(long long int i=0;i<n;i++)
            {
                long long int j=i+p-1;
                if(j>=n)
                    break;
                    if(p<=20)
                        dp[i][j]=a[i]*pow2[j-i+1];
                        else
                            {
                                if(i>0)
                                    dp[i][j]=(sum[j]-sum[i-1])*2;
                                else
                                    dp[i][j]=(sum[j])*2;
                            }
                for(long long int k=i;k<j;k++)
                    dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
            }
        }
        //for(long long int i=0;i<=n-1;i++)
            //cout<<dp[0][i]<<endl;
            cout<<dp[0][n-1]<<endl;
    }
    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值