您的位置:首页 > 其它

整数划分问题

2017-08-08 14:19 239 查看
把100拆分成4个整数之和,有多少种拆分方法。注意1+2+3+94和94+1+2+3只能算一种。

一看到这题,觉得很容易,以为用暴力求解就可以了,但是后面的限制条件不知道怎么写,硬着头皮写了些限制条件,但是算出来的结果非常大,感觉根本不是答案。

在网上到处搜索,看到这种整数划分问题可以用动态规划解决,于是尝试去理解这方面的动态规划。但是看不懂,只好求助班里的大神,大神一直很忙,过了两天,给我发了

视频,六百多兆的视频,大神说,打字说不清,于是发个视频,感动cry,这个太麻烦,没有人给我讲,所以非常谢谢大神。

主要的代码部分是dp
[k]=dp[n-1][k-1]+dp[n-k][k]

即把dp[i][j]分成两个主要的部分:

第一部分:n份中,至少有一份包含1,就减去这个1,把1作为单独的一份,于是本来要分成k份的,现在减去1份,变成k-1份,于是有dp[n-1][k-1]

第二部分:n份中,不包含1的分法,不包含1,就把每一份都减去1,分成k份,就减去k个1,于是有n-k,于是有dp[n-k][k-1]

把这两个子状态相加即可。我看的时候,还有个疑问,这个1到底指的是什么?为什么要按照包含1和不包含1来划分?在学习递归的时候,也有类似的问题,

那时候看一个视频,里面的老师说,假设我们已经把所有的划分都分好了,现在把1当成一个特殊的数字,那么所有的划分就会满足包含1的和不包含1的来划分。

还是似懂非懂,不过就这样理解吧。

java代码:

import java.util.Scanner;

public class Main {

public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int k = input.nextInt();

int[][] num = new int[n+1][n+1];

int i, j;
for(i=0;i<=n;i++)
{
for(j=0;j<=n;j++){
num[i][j] = 0;
}
}

for(i=1; i<=n; i++)
{
for(j=1;j<=n;j++){
if(i < j)
{
num[i][j] = 0;
}
if(i == j)
{
num[i][j] = 1;
}
if(i > j)
{
num[i][j] = num[i-1][j-1] + num[i-j][j];
}
}
}

System.out.println(num
[k]);
}

}

c++代码:

#include <iostream>  

#include <cstdio>  

#include <queue>  

#include <vector>  

#include <map>  

  

using namespace std;  

  

int main()  

{  

    int n, k;  

    while( cin >> n >> k )  

    {  

        int num[n+1][n+1];               

        

        int i, j;                            

        for( i=0; i<=n; i++ )  

        {  

            for( j=0; j<=n; j++ )  

            {  

                num[i][j] = 0;  

            }  

        }  

                                     

        for( i=1; i<=n; i++)  

        {  

            for( j=1; j<=n; j++)  

            {  

                if( i < j )  

                {  

                    num[i][j] = 0;  

                   

                }  

                if( i == j )  

                {  

                    num[i][j] = 1;  

                    

                }  

                if( i > j )  

                {  

                    num[i][j] = num[i-1][j-1] + num[i-j][j];  

                }  

            }  

        }  

        

        cout << num
[k] <<endl;  

    return 0;  

   }

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: