pku acm 1032

有两种方法求解,(1)递归分解,这种方法很好想,但是超时

(2)分析题目,得出一些基本规律。(参考了他人的想法)

1,    a[1] > 1

Proof: If a[1] = 1, a[t] could be replacedby a[t] + 1 and a[t]+1 > a[t] * 1.

 

2, 1 <= a[i+1] – a[i] <= 2

Proof: If exists i make a[i+1] – a[i] >2, then a[i], a[i+1] could be replaced by a[i]+1, a[i+1]-1 together, and (a[i]+1)*(a[i+1] – 1) = a[i]*a[i+1] + a[i+1] – a[i] – 1 > a[i]*a[i+1]+1 >a[i]* a[i+1].

 

3, at most one i makes a[i+1] – a[i] = 2;

Proof: If i < j and a[i+1] – a[i] = 2,a[j+1] – a[j] = 2 then a[i], a[j+1] could be replaced by a[i]+1, a[j+1]-1 and (a[i] + 1)*(a[j+1] - 1 ) = a[i]*a[j+1] + a[j + 1] – a[i]-1. Case 1,  i+1 = j, then (a[i] +1)*(a[j+1] - 1 ) = a[i]*a[j+1] + 3; Case 2, i + 1 <j, then (a[i] + 1)*(a[j+1] - 1 ) > a[i]*a[j+1] + 3.

 

4,  a[1] <=3.

Proof:  if a1>=4, then a1, a2 together could bereplaced by 2, a1-1, a2-1 together.

 

因此可以轻松构造出该序列:

1.从2开始累加,直到和m大于等于n
2.j=m-n,把序列中的j划去(当j=1时,划去2并将最后一个元素加1)



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

int a[110];//存放拆分的数
int result[110];//存放结果
long long maxproduct;
int index = 1;

void rsplit(long long product,int begin)
{
    int k = a[begin];
    int s1,s2,i,j;
    long long p;
    for (j = 1; j <= k/2; ++j)
    {
        s1 = a[begin-1]+j;
        s2 = k - s1;
        if(s2 <= s1)return;

        a[begin] = s1;
        a[begin+1] = s2;
        p = product*s1*s2;
        if(maxproduct < p)
        {
            for (i = 1; i <= begin+1; ++i)
                result[i] = a[i];
            maxproduct = p;
            index = begin+1;
        }
        rsplit(p/s2,begin+1);
    }
}

void split(int N)
{
	int n,i=2, m=0,j;
	n = N;
	while(m<n)
		m += i++;
	j = m-n;
	m = 2;
	if(j == 1)
	{
		m = 3;
		j = i-1;
		i++;
	}

	while(m < i-1)
	{
		if (m!=j)
			printf("%d ",m);
		m++;
	}
	printf("%d\n",i-1);
}

int main()
{
    freopen("in.txt", "rt", stdin);
    cin>>a[1];
    maxproduct=0;
    result[1] = a[1];
    //split(1,1);
	split(a[1]);
   /* for (int i = 1; i <= index; ++i)
        cout<<result[i]<<" ";
    cout<<endl;*/
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值