PAT甲題題解-1103. Integer Factorization (30)-(dfs)


  該題還不錯~。

  題意:給定N、K、P,使得可以分解成N = n1^P + … nk^P的形式,如果可以,輸出sum(ni)最大的划分,如果sum一樣,輸出序列較大的那個。否則輸出Impossible。

  dfs枚舉,為了防止超時,這里要預先將從1開始的i^p的值存儲在factor數組中,直到i^p>n。然后dfs深度優先搜索,相當於把問題一步步分解,即若第一個因子是n1,則接下來我們要判斷N-n1^p、k-1是否可行。同時存儲當前因子的總和sum,要取sum最大的;還有上一次相加的因子的索引last,因為因子要從大到小輸出,所以后一個不能大於前一個因子。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
#include <cmath>
using namespace std;
/*
其實可以預先把i^p<n的i都存儲起來
*/
const int maxn=405;
int res[maxn];
int ans[maxn];
int factor[maxn];
int fidx=0;
int maxsum=0;
bool flag=false;
int n,k,p;
/*
num為當前的總和
cnt為還剩幾個i^p項,即當前的k
sum為各因子的總和,因為要取和最大的
last為上一個因子的索引,因為要保證因子從大到小輸出,
    所以dfs后一個因子在factor中的索引不能大於上一個
*/
void dfs(int num,int cnt,int sum,int last){
    if(num==0&&cnt==0){
        if(sum>maxsum){
            flag=true;
            for(int i=1;i<=k;i++)
                ans[i]=res[i];
            maxsum=sum;
        }
        return;
    }
    else if(cnt==0)
        return;
    for(int i=min(fidx-1,last);i>=0;i--){
        int left=num-factor[i];
        if(left>=cnt-1){
            res[cnt]=i+1;
            dfs(left,cnt-1,sum+i+1,i);
        }
    }
}

int main()
{
    scanf("%d %d %d",&n,&k,&p);
    int tmp=1;
    fidx=0;
    //預先存儲i^p<=n的i
    while(tmp<=n){
        factor[fidx]=tmp;
        fidx++;
        tmp=pow(fidx+1,p);
    }
    int cnt=0;
    int last=fidx-1;

    dfs(n,k,0,last);
    if(flag){
        printf("%d =",n);
        for(int i=k;i>=2;i--){
            printf(" %d^%d +",ans[i],p);
        }
        printf(" %d^%d",ans[1],p);
    }
    else{
        printf("Impossible");
    }

    return 0;
}
View Code

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: