这种问题有两种做法,DP和母函数。
hdu1028 Ignatius and the Princess III
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1028
DP做法:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cctype> 6 #include <stack> 7 #include <queue> 8 #include <deque> 9 #include <map> 10 #include <set> 11 #include <vector> 12 #include <cmath> 13 #include <algorithm> 14 #define lson l, m, rt<<1 15 #define rson m+1, r, rt<<1|1 16 using namespace std; 17 typedef long long int LL; 18 const int MAXN = 0x7fffffff; 19 const int MINN = -0x7fffffff; 20 const double eps = 1e-9; 21 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1}, 22 {1,1},{1,-1},{-1,-1}}; 23 24 int main(void){ 25 #ifndef ONLINE_JUDGE 26 freopen("hdu1028.in", "r", stdin); 27 #endif 28 int i, j, dp[121][121], n; 29 dp[1][1] = 1; // WA! 30 for (i = 2; i < 121; ++i) { 31 dp[i][1] = dp[1][i] = 1; 32 for (j = 2; j < 121; ++j) { 33 if (i > j) dp[i][j] = dp[i-j][j] + dp[i][j-1]; 34 else if (i == j) dp[i][j] = dp[i][j-1] + 1; 35 else dp[i][j] = dp[i][i]; 36 } 37 } 38 while (~scanf("%d", &n)) { 39 printf("%d\n", dp[n][n]); 40 } 41 42 return 0; 43 }
母函数做法:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cctype> 6 #include <stack> 7 #include <queue> 8 #include <deque> 9 #include <map> 10 #include <set> 11 #include <vector> 12 #include <cmath> 13 #include <algorithm> 14 #define lson l, m, rt<<1 15 #define rson m+1, r, rt<<1|1 16 using namespace std; 17 typedef long long int LL; 18 const int MAXN = 0x7fffffff; 19 const int MINN = -0x7fffffff; 20 const double eps = 1e-9; 21 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1}, 22 {1,1},{1,-1},{-1,-1}}; 23 24 int a[121], b[121]; 25 int main(void){ 26 #ifndef ONLINE_JUDGE 27 freopen("hdu1028.in", "r", stdin); 28 #endif 29 int n; 30 while (~scanf("%d", &n)) { 31 int i, j, k; 32 for (i = 0; i <= n; ++i) a[i] = b[i] = 0; 33 a[0] = 1; 34 for (i = 1; i <= n; ++i) { 35 for (j = 0; j <= n; ++j) { 36 for (k = 0; k*i+j <= n; ++k) { 37 b[k*i+j] += a[j]; 38 } 39 } 40 for (j = 0; j <= n; ++j) { 41 a[j] = b[j]; b[j] = 0; 42 } 43 } 44 printf("%d\n", a[n]); 45 } 46 47 return 0; 48 }
hdu2082 找单词
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2082
只写了母函数的。因为这个有个数限制。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cctype> 6 #include <stack> 7 #include <queue> 8 #include <deque> 9 #include <map> 10 #include <set> 11 #include <vector> 12 #include <cmath> 13 #include <algorithm> 14 #define lson l, m, rt<<1 15 #define rson m+1, r, rt<<1|1 16 using namespace std; 17 typedef long long int LL; 18 const int MAXN = 0x7fffffff; 19 const int MINN = -0x7fffffff; 20 const double eps = 1e-9; 21 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1}, 22 {1,1},{1,-1},{-1,-1}}; 23 24 int a[51], b[51]; 25 int main(void){ 26 #ifndef ONLINE_JUDGE 27 freopen("hdu2082.in", "r", stdin); 28 #endif 29 int t; scanf("%d", &t); 30 while (t--) { 31 int i, j, k, num; 32 for (i = 0; i <= 50; ++i) { 33 a[i] = b[i] = 0; 34 } 35 a[0] = 1; 36 for (i = 1; i <= 26; ++i) { 37 scanf("%d", &num); 38 for (j = 0; j <= 50; ++j) { 39 for (k = 0; k <= num && k*i+j <= 50; ++k) { 40 b[k*i+j] += a[j]; 41 } 42 } 43 for (j = 0; j <= 50; ++j) { 44 a[j] = b[j]; b[j] = 0; 45 } 46 } 47 int sum = 0; 48 for (i = 1; i <= 50; ++i) sum += a[i]; 49 printf("%d\n", sum); 50 } 51 52 return 0; 53 }
poj1664 放苹果
题目链接:http://poj.org/problem?id=1664
这道也只写了DP的,用DP处理比较方便。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cctype> 6 #include <stack> 7 #include <queue> 8 #include <deque> 9 #include <map> 10 #include <set> 11 #include <vector> 12 #include <cmath> 13 #include <algorithm> 14 #define lson l, m, rt<<1 15 #define rson m+1, r, rt<<1|1 16 using namespace std; 17 typedef long long int LL; 18 const int MAXN = 0x7fffffff; 19 const int MINN = -0x7fffffff; 20 const double eps = 1e-9; 21 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1}, 22 {1,1},{1,-1},{-1,-1}}; 23 24 int main(void){ 25 #ifndef ONLINE_JUDGE 26 freopen("poj1664.in", "r", stdin); 27 #endif 28 int t, n, m; scanf("%d", &t); 29 int dp[11][11], i, j; 30 dp[1][1] = 1; 31 for (i = 2; i < 11; ++i) { 32 dp[i][1] = dp[1][i] = 1; 33 for (j = 2; j < 11; ++j) { 34 if (i > j) dp[i][j] = dp[i][j-1] + dp[i-j][j]; 35 else if (i == j) dp[i][j] = dp[i][j-1] + 1; 36 else dp[i][j] = dp[i][i]; 37 } 38 } 39 while (t--) { 40 scanf("%d%d", &m, &n); 41 printf("%d\n", dp[m][n]); 42 } 43 44 return 0; 45 }
noj1046 正整数划分问题
题目链接:http://acm.nankai.edu.cn/p1046.html
跟hdu1028一样一样的……其实就是一道题目o(╯□╰)o
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cctype> 6 #include <stack> 7 #include <queue> 8 #include <deque> 9 #include <map> 10 #include <set> 11 #include <vector> 12 #include <cmath> 13 #include <algorithm> 14 #define lson l, m, rt<<1 15 #define rson m+1, r, rt<<1|1 16 using namespace std; 17 typedef long long int LL; 18 const int MAXN = 0x7fffffff; 19 const int MINN = -0x7fffffff; 20 const double eps = 1e-9; 21 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1}, 22 {1,1},{1,-1},{-1,-1}}; 23 24 int main(void){ 25 #ifndef ONLINE_JUDGE 26 freopen("hdu1028.in", "r", stdin); 27 #endif 28 int i, j, dp[121][121], n; 29 dp[1][1] = 1; // WA! 30 for (i = 2; i < 121; ++i) { 31 dp[i][1] = dp[1][i] = 1; 32 for (j = 2; j < 121; ++j) { 33 if (i > j) dp[i][j] = dp[i-j][j] + dp[i][j-1]; 34 else if (i == j) dp[i][j] = dp[i][j-1] + 1; 35 else dp[i][j] = dp[i][i]; 36 } 37 } 38 while (~scanf("%d", &n)) { 39 printf("%d\n", dp[n][n]); 40 } 41 42 return 0; 43 }
感觉这些基础的东西现在都不熟练……
哈哈,附上一首超级好听的钢琴曲~
某青推荐的……THX~