【noi 2.7_7219】复杂的整数划分问题(算法效率)

题意:若干组数据,分别问 N划分成K个正整数之和的划分数目、N划分成若干个不同正整数之和的划分数目、N划分成若干个奇正整数之和的划分数目。

解法:请见我之前的一篇博文内的Article 2——【noi 2.6_8787】数的划分(DP){附【转】整数划分的解题方法} http://www.cnblogs.com/konjak/p/5950919.html

注意——真心初始化要很小心啊!分类讨论最保险了!

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 #define N 55
 7 
 8 int f[N][N],g[N][N];
 9 
10 int main()
11 {
12     int n,k,i,j;
13     while (~scanf("%d%d",&n,&k))
14     {
15     for (i=1;i<=n;i++)
16     {
17      f[i][1]=1;
18      for (j=2;j<=k;j++)
19      {
20        if (i<j) f[i][j]=0;
21        if (i==j) f[i][j]=1;
22        if (i>j) f[i][j]=f[i-1][j-1]+f[i-j][j];
23      }
24     }
25     printf("%d\n",f[n][k]);
26     
27     for (i=1;i<=n;i++)
28     {
29      g[i][1]=(i==1)?1:0;
30      for (j=2;j<=n;j++)
31      {
32        if (i<j) g[i][j]=g[i][i];
33        if (i==j) g[i][j]=g[i][j-1]+1;
34        if (i>j) g[i][j]=g[i][j-1]+g[i-j][j-1];
35      }
36     }
37     printf("%d\n",g[n][n]);
38     
39     for (i=1;i<=n;i++)
40     {
41      f[i][1]=(i%2),g[i][1]=(i%2==0);
42      f[i][0]=f[i][1];
43      for (j=2;j<=n;j++)
44      {
45        if (i<j) f[i][j]=g[i][j]=0;
46        if (i==j) f[i][j]=1,g[i][j]=0;
47        if (i>j)
48        {
49           f[i][j]=f[i-1][j-1]+g[i-j][j];
50           g[i][j]=f[i-j][j];
51        }
52        f[i][0]+=f[i][j];
53      }
54     }
55     /*另一种简洁一点的打法,但我觉得若不能保证对就不要打这样的,不太保险...
56     f[0][0]=1; g[0][0]=1;
57     for(int i=1; i<=n; i++)
58       for(int j=1; j<=i; j++)
59       {
60         g[i][j] = f[i-j][j];
61         f[i][j] = g[i-j][j] + f[i-1][j-1];  
62       }
63     */
64     printf("%d\n",f[n][0]);
65     }
66     return 0;
67 }

 

posted @ 2016-10-27 17:00  konjac蒟蒻  阅读(583)  评论(0编辑  收藏  举报