Target Sum

Target Sum

时间限制:10000ms

单点时限:1000ms

内存限制:256MB

描述

There is a sequence of N positive integers A1, A2, ... AN and a target sum S. You need to add a plus or minus operator (+/-) before every integer so that the resulted expression equals to S. Find out the number of such expressions.

Example if the sequence A is [1, 1, 1, 1, 1] and the target sum S is 3. There are 5 valid expressions: -1+1+1+1+1=3, +1-1+1+1+1=3, +1+1-1+1+1=3, +1+1+1-1+1=3 and +1+1+1+1-1=3.

输入

The first line contains 2 integers N and S denoting the number of integers and the target sum.  

The second line contains N integers A1, A2, ... AN.

For 80% of the data: 1 <= N <= 10

For 100% of the data: 1 <= N <= 100 1 <= S <= 100000 1 <= Ai <= 1000

输出

The number of valid expressions. The answer may be very large so you only need to output the answer modulo 1000000007.

样例输入

扫描二维码关注公众号,回复: 4734299 查看本文章
5 3
1 1 1 1 1

样例输出

5

首先每个数的大小是[1, 1000],所以所有数的和的范围是[-100000, 100000]

我们可以用f[i][j]表示前i个数中,和是(j-100000)一共有几种方法。

这里(j-100000)主要是考虑到数组下标不能是负数。

初始值是f[0][100000] = 1

递推方程大概是f[i][j] = f[i-1][j-A[j]] + f[i-1][j+A[j]],需要考虑一下j-A[j]j+A[j]的范围。

由于f[i][]的值全部是由f[i-1][]计算得来,所以可以用滚动数组优化空间复杂度。

整体的时间复杂度是O(NR)其中R是和的取值范围。


import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        int S = scanner.nextInt();
        int[] a = new int[N];
        for (int i = 0; i < N; i++) {
        	a[i] = scanner.nextInt();
        }
        System.out.println(solve(N, S, a));
        scanner.close();
    }
    
    private static int solve(int N, int S, int[] a) {
    	final int M = 1000000007;
    	int maxSum = 0;
    	for (int i = 0; i < N; i++) {
    		maxSum += Math.abs(a[i]);
    	}
    	int compensate = maxSum + 1000;
    	int[][] dp = new int[N + 1][2 * compensate + 1];
    	dp[1][a[0] + compensate] = 1;
    	dp[1][-a[0] + compensate] = 1;
    	for (int i = 2; i < N + 1; i++) {
    		for (int j = 1000; j <= 2 * maxSum + 1000; j++) {
    			dp[i][j] = (dp[i - 1][j - a[i - 1]] + dp[i - 1][j + a[i - 1]]) % M;
    		}
    	}
    	return dp[N][S + compensate];
    }
}

dfs


import java.util.Scanner;

public class Main {

static int count = 0;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int targetSum = sc.nextInt();
		int[] numbers = new int[n];
		for (int index = 0; index < n; index++) {
			int number = sc.nextInt();
			numbers[index] = number;
		}
		countMatchSum(1, numbers, targetSum - numbers[0]);
		countMatchSum(1, numbers, targetSum + numbers[0]);
		System.out.println(count);
	}

	public static void countMatchSum(int index, int[] numbers, int targetSum) {
		int number = numbers[index++];
		if (numbers.length == index && (number == targetSum || -number == targetSum)) {
			count++;
		}
		if (numbers.length > index) {
			countMatchSum(index, numbers, targetSum - number);
			countMatchSum(index, numbers, targetSum + number);
		}
	}

}

猜你喜欢

转载自blog.csdn.net/weixin_38970751/article/details/85529636
今日推荐