[UVALive 6661 Equal Sum Sets] (dfs 或 dp)
阿新 • • 發佈:2017-06-06
dsm ems live pos algorithm n) uva for %d
題意:
求從不超過 N 的正整數其中選取 K 個不同的數字,組成和為 S 的方法數。
1 <= N <= 20 1 <= K<= 10 1 <= S <= 155
解題思路:
DFS:
因為N,K。S的範圍非常小。直接DFS就可以。
/* ID: [email protected] PROG: LANG: C++ */ #include<map> #include<set> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<vector> #include<string> #include<fstream> #include<cstring> #include<ctype.h> #include<iostream> #include<algorithm> #define INF (1<<30) #define PI acos(-1.0) #define mem(a, b) memset(a, b, sizeof(a)) #define For(i, n) for (int i = 0; i < n; i++) typedef long long ll; using namespace std; int n, k, s; int cnt = 0; void dfs(int sum, int x, int depth) { if (sum > s) return ; if (k - 1 == depth) { if (sum == s) cnt++; return ; } for (int i = x + 1; i <= min(n, s - sum); i++) dfs(sum + i, i, depth + 1); } int main () { while(scanf("%d%d%d", &n, &k, &s)) { if (n + k + s == 0) break; cnt = 0; for (int i = 1; i <= n; i++) { dfs(i, i, 0); } printf("%d\n", cnt); } }
DP:
dp[i][j][k] = dp[i - 1][j][k] + dp[i - 1][j - i][k - 1] //dp[i][j][k]表示從不超過i的數字中選取k個數和為j的方法數。
/* ID: [email protected] PROG: LANG: C++ */ #include<map> #include<set> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<vector> #include<string> #include<fstream> #include<cstring> #include<ctype.h> #include<iostream> #include<algorithm> #define INF (1<<30) #define PI acos(-1.0) #define mem(a, b) memset(a, b, sizeof(a)) #define For(i, n) for (int i = 0; i < n; i++) typedef long long ll; using namespace std; int dp[22][160][11]; int n, k, s; int main () { dp[0][0][0] = 1; for (int i = 1; i <= 20; i++) { for (int j = 0; j <= 155; j++) { for (int k = 0; k <= 10; k++) { dp[i][j][k] = dp[i - 1][j][k]; if (k > 0 && j >= i) dp[i][j][k] += dp[i - 1][j - i][k - 1]; } } } while(scanf("%d%d%d", &n, &k, &s), n || k || s) printf("%d\n", dp[n][s][k]); }
[UVALive 6661 Equal Sum Sets] (dfs 或 dp)