hdu 4570

http://acm.hdu.edu.cn/showproblem.php?pid=4570

 

【题意】:  给出一个长度为n的数列,将其分成若干段,要求最小,其中ai是每一段数列的第一项,bi是每一段的长度,l为将数列分成l段。

 

               题意是百度的  为什么没有人 说 分为同一段的数 要<=20个  ??!!

 

【动态转移方程】   d[i]=min(d[i],d[i-j]+a[i-j+1]*b[j]);    前i个可以得到的最小值  j表示最后一段的长度  【注意】j不能大于20!!

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 
 5 #include<algorithm>
 6 #define INF 0x1f1f1f1f
 7 using namespace std;
 8 
 9 __int64 d[102],a[102],b[102];
10 
11 __int64 min(__int64 a,__int64 b)
12 {
13     return a<b?a:b;
14 }
15 
16 int main()
17 {
18    int t,n;
19     b[0]=1;
20     for(int i=1;i<=20;i++)
21       b[i]=b[i-1]*2;
22    scanf("%d",&t);
23    while(t--)
24    {
25        scanf("%d",&n);
26 
27 
28        d[0]=0;
29        for(int i=1;i<=n;i++)
30             d[i]=INF;
31        for(int i=1;i<=n;i++)
32            scanf("%I64d",&a[i]);
33        for(int i=1;i<=n;i++){
34           for(int j=1;j<=i&&j<=20;j++)
35             {
36 
37                 d[i]=min(d[i],d[i-j]+a[i-j+1]*b[j]);
38             }
39             //printf("maxx  %d\n",d[i]);
40        }
41             printf("%I64d\n",d[n]);
42    }
43 
44     return 0;
45 }

 

posted @ 2014-03-06 20:16  galaxy77  阅读(210)  评论(0编辑  收藏  举报