[ 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 }