UPC-最優分解問題(貪心)

最優分解問題

時間限制: 1 Sec 內存限制: 128 MB
[提交] [狀態]
題目描述
設n是一個正整數。現在要求將n分解爲若干個互不相同的自然數的和,且使這些自然數的乘積最大。
輸入
第1行是正整數n。(n不超過50)
輸出
計算出的最大乘積。
樣例輸入 Copy
10
樣例輸出 Copy
30

具體證明:傳送門

貪心的思想,和一定時,如果兩個數差值越小,乘積就越大(好像是個數學公式?)
所以從2開始枚舉,累加和爲sum,直到sum+i>n時停止
可能會有剩下的值,從後向前依次將該數加1即可。
重點是特判
當n=1時,可以拆成1和0,答案爲0。
當n=2時,只能拆成2和0,答案爲0。
因爲要求拆出來的正整數不相同,所以1和1不可行
當n=3時,可以拆成1和2,答案爲2。
當n>=4時,開始枚舉即可。

坑點就是n=2。。

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
int main(){
    int n;cin>>n;
    if(n<=4){
        if(n==2) cout<<0<<endl;
        else
        cout<<max(n-1,0)<<endl;
        return 0;
    }
    vector<int>v;
    int sum=0;
    for(int i=2;i<=n;i++){
        if(sum+i<=n) v.push_back(i),sum+=i;
        else break;
    }
    int tmp=n-sum;
    ll res=1;
   /// cout<<tmp<<endl;
   /// cout<<v.size()<<endl;
    for(int i=v.size()-1;i>=0;i--){
        if(tmp>0) v[i]++,tmp--;
        else break;
    }
    int ans=0;
    for(auto tt:v){
        ///cout<<tt<<" ";
        res*=tt;
        ans+=tt;
    }
    cout<<res<<endl;
   /// cout<<ans<<endl;
    return 0;
}

補來自學長的證明:

a+b=c
b=c-a
ab=(c-a)a=ac-aa
對稱軸 a=c/2
根據一元二次方程a取 對稱軸左右時最大
從而將問題從兩個數轉換到三個數
至多個數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章