数字和为sum的方法数(动态规划)——网易2017内推笔试编程题

链接: https://www.nowcoder.com/questionTerminal/7f24eb7266ce4b0792ce8721d6259800
来源:牛客网

给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数。
当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案。
输入描述:
输入为两行:
 第一行为两个正整数n(1 ≤ n ≤ 1000),sum(1 ≤ sum ≤ 1000)
 第二行为n个正整数A[i](32位整数),以空格隔开。
输出描述:
输出所求的方案数

分析:

采用动态规划的方法,dp[i][j]表示用前i个值组成和为j的方案个数。

dp[][]=new dp[n+1][sum+1]; n为整数个数,sum为要求的和。

dp[i][j]=dp[i-1][j]+dp[i-1][j-A[i-1]];  dp[i-1][j]表示第i个数不计入,则方案个数还是为dp[i-1][j]. dp[i-1][j-A[i-1]]表示第i个数(下标为i-1,因为i是从1开始的)计入的方案个数.

import java.util.Scanner;

public class Main {
    //给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数。
    //当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案。
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        while(scanner.hasNext()){
            int n=scanner.nextInt();
            int sum=scanner.nextInt();
            int[] A=new int[n];
            for(int i=0;i<n;i++)
                A[i]=scanner.nextInt();
            long[][] dp=new long[n+1][sum+1];  //dp[i][j]表示用前i个值组成和为j的方案个数
            //前i个组成和为0的方案只有1种,即什么都不选
            for(int i=0;i<=n;i++){
                dp[i][0]=1;
            }
            //用0个元素不能组成1-sum
            for(int j=1;j<=sum;j++){
                dp[0][j]=0;
            }

            for(int i=1;i<=n;i++){
                for(int j=0;j<=sum;j++){
                    if(A[i-1]<=j){
                        dp[i][j]=dp[i-1][j]+dp[i-1][j-A[i-1]];
                    }else{
                        dp[i][j]=dp[i-1][j];
                    }
                }
            }
            System.out.println(dp[n][sum]);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_27139155/article/details/80886741