zoukankan      html  css  js  c++  java
  • 洛谷 P1025 数的划分

    https://www.luogu.org/problemnew/show/P1025

    本题有两种解法 dfs和dp

    dfs

    dfs很好理解 只是需要加上一个剪枝:

    sums+i*(k-t)<=n

    其实这个也是很容易理解的 因为我们为了避免重复 将循环从小到大进行 那么如果sums+i*(k-t)>n,说明后面的数肯定不满足条件

    #include<bits/stdc++.h>
    
    using namespace std;
    int n,k,anss,sums;
    
    void dfs(int now,int t)
    {
        if(t==k)
        {
            if(sums==n)
            anss++;
            return;
        }
        for(int i=now;sums+i*(k-t)<=n;i++)
        {
            sums+=i;
            dfs(i,t+1);
            sums-=i;
        }
    }
    
    int main()
    {
        cin>>n>>k;
        dfs(1,0);
        cout<<anss<<endl;
    }

    也可以把sums当作参数传进去:

    #include<bits/stdc++.h>
    
    using namespace std;
    int n,k,anss;
    
    void dfs(int now,int t,int sums)
    {
        if(t==k)
        {
            if(sums==n)
            anss++;
            return;
        }
        for(int i=now;sums+i*(k-t)<=n;i++)
        dfs(i,t+1,sums+i);
    }
    
    int main()
    {
        cin>>n>>k;
        dfs(1,0,0);
        cout<<anss<<endl;
    }

    dp

    这个不是很好想 我是抄的题解:

    f[i][x] 表示 i 分成 x 个非空的数的方案数。

    显然 i<x 时 f[i][x]=0 , i=x 时 f[i][x]=1;

    其余的状态,我们分情况讨论:

    ①有1的 ②没有1的

    第一种情况,方案数为 f[i-1][x-1]

    第二种情况,方案数为 f[i-x][x] (此时 i 必须大于 x)

    所以,状态转移方程为: f[i][x]=f[i-1][x-1]+f[i-x][x]

    解释一下:

    一个数字i被分成K份时,存在两种情况,一个是有一存在,如6分成三份的1 2 3;另一种是没有一存在,比如6分成三份的2 2 2;
    如果有1存在,还是用6分三份举例,那么就是对5进行分两份的操作,再加上那个1;如果没有1存在,我们先将6变成(1+a)+(1+b)+(1+c);那么a+b+c=6-3=3;然后他们需要被分配到三个位置上从而防止1的出现——即【i-k】【k】

    #include<bits/stdc++.h>
    
    using namespace std;
    long long int n,k,a[205][10],i,j;
    int main()
    {
    
        cin>>n>>k;
        for(i=1;i<=n;i++)
        {
            a[i][1]=1;
            a[i][0]=1;
        }
        for(i=2;i<=k;i++)
        {
            a[1][i]=0;
            a[0][i]=0;
        }
        for(i=2;i<=n;i++)
        for(j=2;j<=k;j++)
        {
            if(i>j)
            a[i][j]=a[i-1][j-1]+a[i-j][j];
            else
            a[i][j]=a[i-1][j-1];
        }
        cout<<a[n][k];
     } 
  • 相关阅读:
    幻方~未完待续
    过河(DP)
    生日蛋糕(DFS)
    n皇后问题<dfs>
    POJ 1182_食物链
    POJ 2431 Expedition【贪心】
    POJ 3268_Silver Cow Party
    POJ 1061 青蛙的约会【扩欧】
    【数学】扩展欧几里得算法
    Codeforces 404D Minesweeper 1D
  • 原文地址:https://www.cnblogs.com/dyhaohaoxuexi/p/10953003.html
Copyright © 2011-2022 走看看