啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊我终于调过辣!!!!!(虽然这题非常之水)
我真的怀疑自己是个铁憨憨。为什么本来可以直接上高精的题我非要拆成 (long) (long) 来做?关键是时间好像并不优越?(感觉自己沧桑了许多)
别急着走啊,宁也来康康大数的魅力吧~
好吧我来讲讲题目:设 (dp[i][j]) 为取了前 (i) 位划了 (j) 刀所得的最大的数。我们枚举一下切割点 (u) 就行了。
祭奠我逝去的一个上午。。。
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;
const ll mod = 1e9;
int n, k, num[44];
struct BigNum {
ll a[10];
BigNum() {a[0] = a[1] = a[2] = a[3] = a[4] = 0;}
BigNum operator * (const BigNum x) {
BigNum r; ll tmp; int cur;
for(int i = 4; i >= 0; -- i) {
for(int j = 4; j >= 0; -- j) {
tmp = x.a[i] * a[j];
if(tmp == 0) continue;
cur = i + j - 4;
r.a[cur] += tmp;
if(r.a[cur] % mod != r.a[cur]) r.a[cur - 1] += r.a[cur] / mod, r.a[cur] %= mod;
}
}
return r;
}
}dp[44][10];
int read() {
int x = 0, f = 1; char s;
while((s = getchar()) > '9' || s < '0') if(s == '-') f = -1;
while(s >= '0' && s <= '9') {x = (x << 1) + (x << 3) + (s ^ 48); s = getchar();}
return x * f;
}
void print(const BigNum x) {
bool flag = 0;
if(x.a[0]) printf("%lld", x.a[0]), flag = 1;
for(int j = 1; j < 4; ++ j) {
if(x.a[j - 1] && x.a[j] == 0) for(int i = 1; i <= 9; ++ i) putchar('0');
if(x.a[j] && flag) printf("%09lld", x.a[j]);
else if(x.a[j]) printf("%lld", x.a[j]), flag = 1;
}
if(flag) printf("%09lld
", x.a[4]);
else printf("%lld
", x.a[4]);
}
BigNum Max(const BigNum x, const BigNum y) {
for(int i = 0; i < 5; ++ i)
if(x.a[i] > y.a[i]) return x;
else if(x.a[i] < y.a[i]) return y;
return x;
}
BigNum Get(BigNum x, const int y) {
for(int i = 0; i < 5; ++ i) x.a[i] = (x.a[i] << 1) + (x.a[i] << 3);
x.a[4] += y;
for(int i = 4; i > 0; -- i)
if(x.a[i] % mod != x.a[i]) x.a[i - 1] += x.a[i] / mod, x.a[i] %= mod;
return x;
}
BigNum get(const int l, int r) {
BigNum res; int cur = 4;
while(r - l + 1 > 0) {
if(r - l + 1 >= 9) {
for(int i = r - 8; i <= r; ++ i)
res.a[cur] = (res.a[cur] << 1) + (res.a[cur] << 3) + num[i];
r -= 9;
}
else {
for(int i = l; i <= r; ++ i)
res.a[cur] = (res.a[cur] << 1) + (res.a[cur] << 3) + num[i];
r = l - 1;
}
-- cur;
}
return res;
}
int main() {
char ch[44];
n = read(), k = read(); scanf("%s", ch + 1);
for(int i = 1; i <= n; ++ i) num[i] = ch[i] - '0';
for(int i = 1; i <= n; ++ i) dp[i][0] = Get(dp[i - 1][0], num[i]);
for(int i = 1; i <= n; ++ i) {
for(int j = 1; j <= min(k, i); ++ j) {
for(int u = 1; u < i; ++ u) dp[i][j] = Max(dp[i][j], dp[u][j - 1] * get(u + 1, i));
}
}
print(dp[n][k]);
return 0;
}