洛谷——P1025 数的划分

P1025 数的划分

题目描述

将整数nn分成kk份,且每份不能为空,任意两个方案不相同(不考虑顺序)。

例如:n=7n=7,k=3k=3,下面三种分法被认为是相同的。

$1,1,51,1,5;$
$1,5,11,5,1;$
$5,1,15,1,1.$

问有多少种不同的分法。

输入输出格式

输入格式:

 

n,kn,k (6<n \le 2006<n200,2 \le k \le 62k6)

 

输出格式:

 

11个整数,即不同的分法。

 

输入输出样例

输入样例#1: 复制
7 3
输出样例#1: 复制
4

说明

四种分法为:
$1,1,51,1,5;$
$1,2,41,2,4;$
$1,3,31,3,3;$
$2,2,32,2,3.$

 

数据小,$dfs$完全可以水过去

#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<cmath>
#include<algorithm>

#define N 110000
#define ll long long
#define RE register

void read(int &x){
    x=0;int flg=1;char ch=getchar();
    for(;ch<'0'||ch>'9';) {if(ch=='-') flg=-1;ch=getchar();}
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
    x=x*flg;
}


using namespace std;
int n,k,ans;

void dfs(int last,int sum,int c){
    if(c==k){
        if(sum==n) ++ans;
        return;
    }else{
        for(int i=last;sum+i*(k-c)<=n;i++){
            dfs(i,sum+i,c+1);
        }
    }
}
int main()
{
    read(n);read(k);
    dfs(1,0,0);
    printf("%d",ans);
    return 0;
}
DFS

 

划分型DP

$F[i][j]$表示$i$分成$m$份的方案数

状态转移方程:$F[i][j]=F[i-1][j-1]+F[i-j][j]$

状态转移方程的意义:将$i$分成$j$份,相当于由将$i-1$分成$j-1$份在添加$1$转移过来;并且由将$i-j$划分为$j$份,这$j$份再次每一个都+1,不就变成了$i$了吗。

#include<iostream>
#include<cstdio>

using namespace std;

int n,m,f[205][105];

int main()
{
    scanf("%d%d",&n,&m);
    f[0][0]=1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m&&j<=i;j++){
            f[i][j]=f[i-1][j-1]+f[i-j][j];
        }
    }
    printf("%d\n",f[n][m]);
    return 0;
}

 

posted @ 2018-09-06 15:02  清风我已逝  阅读(303)  评论(0编辑  收藏  举报