#include<stdio.h>
#include<string.h>
int k, pp[20];
long long sum, ff[20][20], max;
void dfs(int n[], int m, int count, int q)
{
int main()
{
#include<string.h>
int k, pp[20];
long long sum, ff[20][20], max;
void dfs(int n[], int m, int count, int q)
{
if(count == m)
{
sum = 1;
for(int i = 0; i <= count; i++)
sum *= ff[pp[i]][pp[i + 1]];
if(sum > max)
max = sum;
}
else
{
for(int i = q; i <= k - 1; i ++)
{
pp[count + 1] = i;
dfs(n, m, count + 1, i + 1);
}
}}
int main()
{
int T, t;
int m, n[20];
char s[20];
scanf("%d", &T);
while(T--)
{
pp[0] = 0;
max = 0;
sum = 1;
memset(ff, 0, sizeof(ff));
scanf("%s %d", s, &m);
for(int i = 0; s[i] != '\0'; i++)
{
n[i] = s[i] - '0';
t = i;
}
k = t + 1;
pp[m] = k;
for(int i = 0; i <= k; i++)
for(int j = i + 1; j <= k; j ++)
for(int p = i; p < j; p ++)
ff[i][j] = ff[i][j] * 10 + n[p];
//for(int i = 0; i <= k; i ++)
// for(int j = 0; j <= k; j++)
// printf("%lld\n", ff[i][j]);
dfs(n, m - 1, 0, 1);
printf("%lld\n", max);
}
return 0;
}
思路:搜索,刚开始用的是全排列的思想来搜,超时。
其实用组合的思想来搜就好,要插入m-1个乘号,总共有k - 1(假设n的长度位k)个地方可以插,那么就是从k-1个中选m-1个。
还有就是,搜之前要预处理,用二位数组来保存每一个区间的值。
铭记:1,尽量以后用n[i] = s[i] - '0'来代替n[i] = s[i] - 48,因为代码尽量要别人看一眼就懂。s[i]前面不必加(int)。
2,很多题都可以用搜索来做,要想清楚是全排列还是组合思想,全排列思想很可能会超时。
3,组合的优化,传下标比用hash标记好很多。