1. 程式人生 > >洛谷——P1025 數的劃分

洛谷——P1025 數的劃分

不同的 fff ret define sample esp problem 輸入輸出 過去

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;
}

洛谷——P1025 數的劃分