P1018 乘积最大

啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊我终于调过辣!!!!!(虽然这题非常之水

我真的怀疑自己是个铁憨憨。为什么本来可以直接上高精的题我非要拆成 (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;
}
原文地址:https://www.cnblogs.com/AWhiteWall/p/12447372.html