poj 1032 将一个数分成几个不同的数之和,满足这些数的乘积最大。

题目:将一个数分成几个不同的数之和,满足这些数的乘积最大。

       刚开始,没有看清“不同”两个字,发现一个数被分成两个数的两个积满足最大,则两个数的差一定要最小。即有两种情况:

                 (1)奇数(2*n+1):则可以分为n和(n+1);

                 (2)偶数(2*n):则可以分为n和n;

      一直分下去,同时考虑到,4 = 2*2,即小于4的数,不用再分了,因为再分其乘积就小于原来的数了。于是,按照这个思路,有如下代码:

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class Parliament{
	friend istream& operator>>(istream &is, Parliament& p)
	{
		is>>p.delegates;
		return is;
	}
public:
	void solution(void)
	{
		calNum(delegates);
		cout<<"delegates="<<delegates<<endl;
		sort(res.begin(),res.end());
		for(int i=0;i!=res.size();i++){
			cout<<res[i]<<" ";
		}
		cout<<endl;
	}
	void calNum(int n)
	{
		if(n<=4){
			res.push_back(n);
			return;
		}

		calNum(n>>1);
		calNum(n-(n>>1));
	}
private:
	int delegates;
	vector<int>res;
};

int main()
{
	Parliament poj1032;
	cin>>poj1032;
	poj1032.solution();
	system("pause");
	return 0;
}

自然上面的思路不满足题目要求。

 

看清题意,也是参考了网上牛人们的思路:

  1. 我们首先先撇开“每组的人数不同”这一约束条件,我们发现如10可以拆成5+5,它的乘积最大, 
  2. 而5又可拆成2+3;2*3>5;故我们发现每次的每一个数都拆成两个相等或相差1的两个数乘积最大。而最大的当然是一直拆到出现2; 
  3. 我们在回来考虑“每组的人数不同”这一约束条件;每组的人数不能相等,但我们又要使数拆成最小的部分(最好拆到出现2), 
  4. 比如说2.3.4~~,那我们大可从2加起,2+3+4+~~~一直加到接近所要求的数;如26我们可以用个循环得到2+3+4+5+6,然后让它停下, 
  5. 此时还剩余6(26-2-3-4-5-6)没用完;那我们就从加数序列的最大那个数开始倒序一次加一,这样过后加数序列就变成了3+4+5+6+7了, 
  6. 但还有1没用啊,当然加给最大的那个7(这个过程用一个取模运算就行了);所以最后答案是3+4+5+6+8*/ 

 

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class Parliament{
	friend istream& operator>>(istream &is, Parliament& p)
	{
		is>>p.delegates;
		return is;
	}
public:
	void solution(void)
	{
		int i = 2,j;
		int sum = 0;
		while(sum+i<=delegates){
			sum += i++;
		}
		int m = delegates - sum;
		if(m == i-1){
			for(j = 3;j<i;j++)cout<<j<<" ";
			cout<<i+1;
		}else{
			for(j=2;j<i-m;j++ )
				cout <<j<<" " ;
			while(j<i){
				cout<<j+1<<" " ;
				j++ ;
			}
			cout<<endl ;
		}
	}
private:
	int delegates;
	vector<int>res;
};

int main()
{
	Parliament poj1032;
	cin>>poj1032;
	poj1032.solution();
	system("pause");
	return 0;
}


 

 

你可能感兴趣的:(poj 1032 将一个数分成几个不同的数之和,满足这些数的乘积最大。)