您的位置:首页 > 其它

贪心算法求所有分解方法中各加数乘积的最大值

2016-11-13 18:01 267 查看
设n为一自然数,n可以分解成若干个不同的自然数的和,这样的分法有很多种,比如n=10, 10可以分解为:10=5+4+1; 10=5+3+2; 10+9+1; 10=8+2; 10=7+3; 10=6+4; 10=7+2+1; 10=6+3+1;…。在所有这些分法中,各加数乘积最大的为30,(10=5+3+2中加数的乘积为5*3*2=30)。试编写程序,求各种分解方法中各加数乘积的最大值。

输入要求:输入只有1行,自然数n。

输出要求:输出也只有1行,所有分解方法中各加数乘积的最大值。

题目已经要求不同自然数,因此根据数学原理,分解的数越接近,它们的乘积是最大的,而且不要分解出1,至少从2开始。
所以从2开始依次递增,直到最后的和大于该数,由于数是按递增排列的,故如果最后拆解的数不是递增的话则将其依次递减加到前面较大的数中,因为为了保证分解的数接近而且较大的数增加的多效果更好。
参考代码:
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <string>
#include <ctime>
#define fur(i,a,b) for(int i=(a);i<=(b);i++)
#define furr(i,a,b) for(int i=(a);i>=(b);i--)
#define cl(a,b) memset((a),b,sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
const int mod=1000000007;
const double pi=acos(-1.0);
const int N = 1000;
int s
= { 0 };
int top;
int sum;
int n,k,m;
int time_

= { 0 };
int min_t;
void dfs(int x)//先用dfs求出所有可能的加数
{
int i;
int temp=0;
if (sum == m) {
for (int p = 0; s[p] != 0; p++)
{
if (s[p] > k || p >= n) return;
temp += time_[p][s[p]];
}
if (temp < min_t)
min_t = temp;
return;
}
if (sum>m)return;
for (i = 1; i <= m; i++)//从1开始实现所有顺序
{
sum += i;
s[top++] = i;
dfs(i);
sum -= i;
s[top--] = 0;
}
}
void MinTimeSolute()
{
min_t = mod;
top = 0;
sum = 0;
dfs(1);
}
int main(){

while (scanf("%d %d %d", &n, &k, &m)==3)
{
for (int i = 0; i < n; i++)
for (int j = 1; j <= k; j++)
scanf("%d", &time_[i][j]);
MinTimeSolute();
printf("%d", min_t);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  贪心算法 acm 算法
相关文章推荐