hdu1028

来源:互联网 发布:php socket epoll 编辑:程序博客网 时间:2024/06/05 19:34

题解:

画出解答树,每个结点有两个值(暂时叫左值和右值)不断划分,原则是将大数化为小数,左值大于右值,结点左值的子树的右值大于等于结点的右值。

n = 5、6、7、8时解答树如下:

由n=8的解答树,可知该解答树有4个子树记作A[8][1]、A[8][2]、A[8][3]、A[8][4]

A[8][1] = A[7][1] + A[7][2] + A[7][3] + 1.

A[8][2] = A[6][2] + A[6][3] + 1

A[8][3] = A[5][3] + 1

A[8][4] = A[4][4] + 1

记A[8][0]为n=8的总结点,则A[8][0] = A[8][1] + A[8][2] + A[8][3] + A[8][4] + 1

由此规律,代码如下:

#include <stdio.h>int A[121][70];int main(){int n, i, j, k;for (k=1; k<=120; k++){A[k][0] = 1;for (i=1; i<=k/2; i++){for (j=i; j<=(k-i)/2; j++)A[k][i] += A[k-i][j];A[k][i] += 1;A[k][0] += A[k][i];}}while (scanf("%d", &n) != EOF)printf("%d\n", A[n][0]);return 0;}


DFS解答树,代码如下

#include <stdio.h>int cnt;//记录个数void dfs(int n, int m){int i;cnt++;for (i=n-1; i>=m; i--)if (i>=n-i && n-i>=m)dfs(i, n-i);}int main(){int n, i;while (scanf("%d", &n) != EOF){//将大的化成小的,小到不能再小为止cnt = 1;for (i=n-1; i>=(n+1)/2; i--)//效率忒低,严重超时,只可供于分析dfs(i, n-i);printf("%d\n", cnt);}return 0;}


 

原创粉丝点击