[ CodeVS冲杯之路 ] P1017

  不充钱,你怎么AC?

  题目:http://codevs.cn/problem/1017/

 

  看到题目最下面有一个喜人的提示

  

  那这就意味着我们不用写高精度了是不是,直接开 long long 存

  设 f[i][j] 表示第 i 个乘号放在第 j 个位置(显然一共有 n-1 个位置)

  

  其中 n 表示数字个数,m 表示需要加上的乘号个数

  初始状态 f[1][i]=a[1][i]*a[i+1][n]   i=1~n-1

  a[i][j] 是原数区间 [i,j] 内的数,当 i=j 时 a[i][j] 易得,当 i≠j 时递推可得

   

  k 是用来控制区间长度的

  目标状态为 max(f[m][i])   i=m~n-1

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<algorithm>
 7 typedef long long LL;
 8 using namespace std;
 9 
10 const int N=41,M=7;
11 LL s,a[N][N],f[M][N],ans;
12 int main()
13 {
14     int n,m,i,j,k;
15     cin>>n>>m>>s;
16     i=n;
17     while (s>0)
18     {
19         a[i][i]=s%10;
20         i--;
21         s/=10;
22     }
23     for (k=1;k<n;k++)
24         for (i=1;i<=n-k;i++) a[i][i+k]=a[i][i+k-1]*10+a[i+k][i+k];
25     for (i=1;i<n;i++) f[1][i]=a[1][i]*a[i+1][n];
26     for (i=2;i<=m;i++)
27         for (j=i;j<n;j++)
28             for (k=1;k<j;k++)
29             {
30                 f[i][j]=max(f[i][j],f[i-1][k]/a[k+1][n]*a[k+1][j]*a[j+1][n]);
31                 if (i==m) ans=max(ans,f[i][j]);
32             }
33     if (m==1) for (i=1;i<n;i++) ans=max(ans,f[1][i]);
34     cout<<ans<<endl;
35     return 0;
36 }

 

posted @ 2016-09-18 16:39  Hadilo  阅读(416)  评论(0编辑  收藏  举报