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 ",d[i]); 40 } 41 printf("%I64d ",d[n]); 42 } 43 44 return 0; 45 }