http://acm.hdu.edu.cn/showproblem.php?pid=5938
题意,给出一串数字,在这串数字中按顺序插入+ - * /,问能得到最大的数字是多少。比如样例,1+2-3*4/5=1.
解法:很明显大小为20的字符串,肯定要开long long。如果直接枚举四个位置复杂度就是20^4,会TLE。所以我把它拆开出来,我枚举+和-的位置,记录下若该位置为-时候能得到最大的数字。然后枚举- * /的位置,记录下该位置若为- * /时候可以得到的最小值。最后for一遍减号能取到的位置,看看哪个位置Max - Min最大,记录下来,即为答案。复杂度降为n^3。
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll sum, a[100005], ans;
int main() {
ll T, n, k, Case = 1;
cin >> T;
while(T--) {
sum = 0;
scanf("%I64d%I64d", &n, &k);
for(int i = 0; i < n; i++) {
scanf("%I64d", &a[i]);
sum += a[i];
}
if(sum % k == 0) {
ll ave = sum / k;
ans = 0;
for(int i = 0; i < n; i++) {
if(a[i] < ave) {
for(int j = i + 1; j < n; j++) {
a[i] += a[j];
ans += 1;
if(a[i] == ave) {
i = j;
break;
}
else if(a[i] > ave) {
ans += a[i] / ave;
a[j] = a[i] - a[i] / ave * ave;
if(a[j]) {
i = j - 1;
} else {
i = j;
ans--;
}
break;
}
}
} else if(a[i] > ave) {
ans += a[i] / ave;
a[i] = a[i] - a[i] / ave * ave;
if(a[i])
i = i - 1;
else
ans--;
}
}
printf("Case #%I64d: %I64d\n", Case++, ans);
} else {
printf("Case #%I64d: -1\n", Case++);
}
}
return 0;
}

本文介绍了一种算法,用于解决给定一系列数字后通过插入基本算术运算符(加、减、乘、除)来获得最大可能数值的问题。通过巧妙地降低枚举复杂度,从初始的O(n^4)降至O(n^3),并提供了实现这一算法的C++代码示例。
&spm=1001.2101.3001.5002&articleId=75645975&d=1&t=3&u=8551ff303a1e4fcfaebf7ef36b411f80)
116

被折叠的 条评论
为什么被折叠?



