Ignatius and the Princess III(n的m划分)

原题链接
Ignatius and the Princess III
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 19041 Accepted Submission(s): 13385

Problem Description

“Well, it seems the first problem is too easy. I will let you know how foolish you are later.” feng5166 says.

“The second problem is, given an positive integer N, we define an equation like this:
N=a[1]+a[2]+a[3]+…+a[m];
a[i]>0,1<=m<=N;
My question is how many different equations you can find for a given N.
For example, assume N is 4, we can find:
4 = 4;
4 = 3 + 1;
4 = 2 + 2;
4 = 2 + 1 + 1;
4 = 1 + 1 + 1 + 1;
so the result is 5 when N is 4. Note that “4 = 3 + 1” and “4 = 1 + 3” is the same in this problem. Now, you do it!”

Input

The input contains several test cases. Each test case contains a positive integer N(1<=N<=120) which is mentioned above. The input is terminated by the end of file.

Output

For each test case, you have to output a line contains an integer P which indicate the different equations you have found.

Sample Input

4
10
20

Sample Output

5
42
627

题意就是说有n个无区别的物品,将他们划分成n组,每组的范围是0~n,问一共有多少种分法?
这个题可以用动态规划做,也可以用递归来做。动态规划速度快,递归好写。
用动态规划就需要想,dp[i][j]如果代表j的i种划分的话,那么情况可以分为两种,一种是没有第i种划分的情况,那么一共就有dp[i-1][j]种情况(注意里面包含有的组是0的情况),然后再有一种一定有第i种划分的情况,那么此时所有的组一定是有一个数的,所以总数就剩下了dp[i][j-1*i]即dp[i][j-i]的情况。两者的和自然就是j的i种划分

#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <string>
using namespace std;
/** Constant List .. **/
const int MOD = int(1e9) + 7;
//int MOD = 99990001;
const int INF = 0x3f3f3f3f;
//const LL INFF = 0x3f3f3f3f3f3f3f3fLL;
//const DB EPS = 1e-9;
//const DB OO = 1e20;
//const DB PI = acos(-1.0); //M_PI;
const int fx[] = {-1, 1, 0, 0};
const int fy[] = {0, 0, -1, 1};
const int maxn=120 + 5;
int dp[maxn][maxn];//dp[i][j]代表j的i种划分
int main(){
        int n;
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;
        for(int i=1;i<=120;i++){
                for(int j=0;j<=120;j++){//注意这里的j是从0开始的,这一点要注意
                        if(j-i>=0)
                                dp[i][j]=dp[i-1][j]+dp[i][j-i];
                        else
                                dp[i][j]=dp[i-1][j];
                }
        }
        while(scanf("%d",&n)==1){
                cout << dp[n][n] << endl;
        }
        return 0;
}

下面是已经打好的表和打表的程序

#include <iostream>
using namespace std;
int getsum(int m,int n){
        if(n==1 || m==1)
                return 1;
        if(n>=m)
                return getsum(m-1,n)+getsum(m,n-m);
        else
                return getsum(m-1,n);
        }
int a[121]={0,1,2,3,5,7,11,15,22,30,42,56,77,101,135,176,231,297,385,490,627,
792,1002,1255,1575,1958,2436,3010,3718,4565,5604,6842,8349,10143,12310,14883,
17977,21637,26015,31185,37338,44583,53174,63261,75175,89134,105558,124754,147273,
173525,204226,239943,281589,329931,386155,451276,526823,614154,715220,831820,966467,
1121505,1300156,1505499,1741630,2012558,2323520,2679689,3087735,3554345,4087968,
4697205,5392783,6185689,7089500,8118264,9289091,10619863,12132164,13848650,15796476,
18004327,20506255,23338469,26543660,30167357,34262962,38887673,44108109,49995925,
56634173,64112359,72533807,82010177,92669720,104651419,118114304,133230930,150198136,
169229875,190569292,214481126,241265379,271248950,304801365,342325709,384276336,
431149389,483502844,541946240,607163746,679903203,761002156,851376628,952050665,
1064144451,1188908248,1327710076,1482074143,1653668665,1844349560};
int main(){
        int n;
        while(cin >> n)
                cout << a[n] << endl;
        return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

门豪杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值