P1018最大積
質問の意味:文字列s(| s | <= 40)があり、k(k <= 6)の乗算記号を与え、最大数を取得するために組み合わせる方法を尋ねます。
解決策:この質問は難しくありません!複雑すぎます!40ビットデータの場合、高精度のみを使用できます。メソッドはdpであり、qj [i] [j](i≤j)はij内のs文字列位置の部分文字列を表します。dp[i] [j]はiの終わりにj個の乗算記号を使用して得られる最大数の場合、伝達方程式は次のようになります。dp[i] [j] = max(dp [i] [j]、dp [x] [j − 1] ∗ qj [x + 1] [i])dp [i] [j] = max(dp [i] [j]、dp [x] [j-1] * qj [x + 1] [i])d p [ i ] [ j ]=m a x (d p [ i ] [ j ] 、d p [ x ] [ j−1 ]∗q j [ x+1 ] [ i ] )、境界の問題に注意してください。
コード:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int ne[4][2] = {
1, 0, 0, 1, -1, 0, 0, -1};
const int N = 50;
int n, k;
string s;
string max(string a, string b) {
if(a.size() != b.size()) return a.size() < b.size() ? b : a;
return a < b ? b : a;
}
//高精度加法
string add(string a, string b) {
string res = "", r = "";
int jw = 0, l1 = a.size(), l2 = b.size();
int p1 = l1-1, p2 = l2-1, mid;
while(p1 >= 0 && p2 >= 0) {
mid = a[p1--]-'0'+b[p2--]-'0'+jw; jw = 0;
r = (mid%10)+'0';
res.insert(0, r);
if(mid >= 10) jw = mid/10;
}
while(p1 >= 0) {
mid = a[p1--]-'0'+jw; jw = 0;
r = (mid%10)+'0';
res.insert(0, r);
if(mid >= 10) jw = mid/10;
}
while(p2 >= 0) {
mid = b[p2--]-'0'+jw; jw = 0;
r = (mid%10)+'0';
res.insert(0, r);
if(mid >= 10) jw = mid/10;
}
if(jw) res.insert(0, "1");
return res;
}
//高精度乘法
string mul(string a, string b) {
string res = "", r1 = "", r;
int jw = 0, l1 = a.size(), l2 = b.size();
int mid, num_0 = 0;
for(int i = l2-1; i >= 0; --i) {
r1 = "";
for(int j = l1-1; j >= 0; --j) {
mid = (b[i]-'0')*(a[j]-'0')+jw; jw = 0;
r = (mid%10) + '0';
r1.insert(0, r);
if(mid >= 10) jw = mid / 10;
}
if(jw) {
r = jw + '0', r1.insert(0, r); jw = 0; }
for(int j = 0; j < num_0; ++j) r1.append("0");
++num_0;
res = add(res, r1);
}
return res;
}
string qj[N][N], dp[N][N];
int main() {
cin >> n >> k >> s;
int len = s.size();
for(int i = 0; i < len; ++i) for(int j = i; j < len; ++j)
qj[i][j] = s.substr(i, j-i+1);
//预处理
for(int i = 0; i < len; ++i) {
dp[i][0] = qj[0][i];
for(int j = 1; j <= k; ++j) dp[i][j] = "0";
}
//dp!
for(int i = 0; i < len; ++i) {
for(int j = 1; j <= k; ++j) {
for(int x = j-1; x < len; ++x) {
dp[i][j] = max(dp[i][j], mul(dp[x][j-1], qj[x+1][i]));
}
}
}
cout << dp[len-1][k] << endl;
return 0;
}