整数划分(四)
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
3
-
描述
-
暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy
(ps:你懂得),可是他最近遇到了一个难题,让他百思不得其解,他非常郁闷。。亲爱的你能帮帮他吗?
问题是我们经常见到的整数划分,给出两个整数 n , m ,要求在 n 中加入m - 1 个乘号,将n分成m段,求出这m段的最大乘积
-
输入
-
第一行是一个整数T,表示有T组测试数据
接下来T行,每行有两个正整数 n,m ( 1<= n < 10^19, 0 < m <= n的位数);
输出
- 输出每组测试样例结果为一个整数占一行 样例输入
-
2 111 2 1111 2
样例输出
-
11 121
思路:1 子集,下一个符号必须放在前一个符号之后2 对在空位的编号进行搜索处理:1 数字有多少位?字符串明白2 空位在哪?空位编号:0~len,其中num【0】 = 0, num【m】 =len3 两个空位之间的数字是多大?二维数组#include<stdio.h> #include<string.h> #define N 20 int len, m, num[N];//num【】来存放第几个空位的位置 long long d[N][N];//存放第i个空位和第j个空位之间数字是多少 long long ans, sum;//sum是当前的结果 char a[N];//输入 void cal(){ sum = 1; int x, y; int i; for(i = 1; i <= m; i++){//遍历到最后一个空格之后,设定最后一个空格就是最后一个数字之后 x = num[i-1]; y = num[i]; sum *= d[x][y]; } } void dfs(int p, int l){ int i; int x, y; if(l > m-1){//多于m-1个符号,return cal(); ans = sum > ans ? sum : ans; return; } else{ for(i = p; i < len; i++){//空位的可能情况是1 ~ len-1 num[l] = i; dfs(i+1, l+1); } } } int main() { int T; int i, j; scanf("%d", &T); while(T--){ ans = 0; memset(d, 0, sizeof(d)); scanf("%s %d",a, &m); if(m == 1){//剪枝,如果没有乘号那么输出的原数 puts(a); continue; } len = strlen(a); num[m] = len;//最后一个空格就是最后一个数字之后 for(i = 0; i < len; i++) for(j = i + 1; j <= len; j++){ if(j == i + 1) d[i][j] = a[i] - '0'; else//画一画就知道了 d[i][j] = d[i][j-1] * 10 + a[j-1] - '0'; //第2个空位对应的字母是a【2-1】 } dfs(1, 1); printf("%lld\n", ans); } return 0; }
-
测试数据:
-
1
-
1234 2
-
492
-
第一行是一个整数T,表示有T组测试数据