1. 程式人生 > >PAT甲級1103 Integer Factorization【dfs】【剪枝】

PAT甲級1103 Integer Factorization【dfs】【剪枝】

printf cto pin ger iostream 思路 ems cstring 等於

題目:https://pintia.cn/problem-sets/994805342720868352/problems/994805364711604224

題意:

給定一個數n,要求從1~n中找出k個數,使得這些數的p次方之和等於n

思路:

因為n為400,所以dfs加剪枝【本來還在想dp來著】

他要求輸出的方案是數字之和最大的,如果之和相等要輸出字典序較大的。

所以還需維護一個數字之和。

一個剪枝的方法是從大到小進行dfs,後面被選的數一定比前面被選的要小,這裏不限制的話顯然會出現重復。

如果從大到小進行dfs的話,tmpsum=anssum的時候,後面的方案一定不如前面的方案,所以這裏不取等號

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<map>
 4 #include<set>
 5 #include<iostream>
 6 #include<cstring>
 7 #include<algorithm>
 8 #include<vector>
 9 #include<cmath> 
10 #include<stack>
11 #include<queue>
12
13 #define inf 0x7fffffff 14 using namespace std; 15 typedef long long LL; 16 typedef pair<string, string> pr; 17 18 int n, k, p; 19 vector<int>ans, tmp; 20 int anssum = 0, tmpsum = 0; 21 22 int ppow[405]; 23 24 void init() 25 { 26 for(int i = 1; i <= n; i++){ 27 ppow[i] = pow(i, p);
28 } 29 } 30 31 void dfs(int i, int num, int sum) 32 { 33 if(num == 0){ 34 if(sum == 0 && tmpsum > anssum){ 35 anssum = tmpsum; 36 ans = tmp; 37 } 38 return; 39 } 40 if(sum < 0)return; 41 42 for(int j = i; j >= 1; j--){ 43 tmp.push_back(j); 44 tmpsum += j; 45 dfs(j, num - 1, sum - ppow[j]); 46 tmp.pop_back(); 47 tmpsum -= j; 48 } 49 } 50 51 52 int main() 53 { 54 scanf("%d%d%d", &n, &k, &p); 55 init(); 56 dfs(n, k, n); 57 //printf("%d\n", ans.size()); 58 if(ans.size() != k){ 59 printf("Impossible\n"); 60 } 61 else{ 62 63 printf("%d = %d^%d", n, ans[0], p); 64 for(int i = 1; i < k; i++){ 65 printf(" + %d^%d", ans[i], p); 66 } 67 printf("\n"); 68 } 69 return 0; 70 }

PAT甲級1103 Integer Factorization【dfs】【剪枝】