您的位置:首页 > 其它

JOJ 2412 Divide the finger

2010-07-12 00:30 246 查看
题意:把一个不超过16位的数字分成m份,求乘积最大值。一个例子:12345拆成两部分,1234|5、123|45 ......,但是最大值是1234 * 5 = 6170

思路:动态规划,f(i, j, t)表示数字的第i位到j位,拆成t部分的最大值。方程:f(i, j, t) = max { f(i, k, 1) * f(k+1, j, t-1) } , k = i..(j-t+1) ;

即, t份的乘积最大值,等于 最左面1份的最大值 与 其余t-1份的最大值 的最大值。-----最优性原理。决策k把问题分成两个子问题

代码:

代码

#include<cstdio>
#include<cstring>
using namespace std;

int n, m;
char num[20];
long long dp[20][20][20];

long long str_int(int i, int j){//i<=j
long long b, s;
b = 1;
s = 0;
for(int k=j; k >= i; --k){
s += (num[k] - '0') * b;
b *= 10;
}
return s;
}

void process(){
int i, j, t, k;
long long max, tmp;
for(i=1; i<=n; ++i)
for(j=i; j<=n; ++j)
dp[i][j][1] = str_int(i, j);
for(t=2; t<=m; ++t)//分成t份
for(i=1; i<=n; ++i)
for(j=i+t-1; j<=n; ++j){
max = 0;
for(k=i; j-k+1 >= t; ++k){
tmp = dp[i][k][1] * dp[k+1][j][t-1];
if(tmp > max)
max = tmp;
}
dp[i][j][t] = max;
}
}

int main(){
//    freopen("in", "r", stdin);

while(scanf("%s %d", &num[1], &m) != EOF){
n = strlen(&num[1]);

process();

printf("%lld\n", dp[1]
[m]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: