1. 程式人生 > >洛谷-【動態規劃】- P1566 加等式

洛谷-【動態規劃】- P1566 加等式

題目描述

對於一個整數集合,我們定義“加等式”如下:集合中的某一個元素可以表示成集合內其他元素之和。如集合{1,2,3}中就有一個加等式:3=1+2,而且3=1+2 和3=2+1是相同的加等式,也是這個集合唯一的加等式。給定一個整數集合,程式設計找出其所有的加等式的個數

輸入輸出格式

輸入格式:

第一行為t,表示測試資料組數。(1≤t≤10);

接下來t 行,每行表示一組測試資料。其中第一個數m(1≤m≤30),表示集合元素的個數,接下來m 個不同的整數x 分別表示集合元素(1≤x≤1000)。

輸出格式:

對於每個輸入資料,輸出一個整數,表示其中加等式的個數。

輸入輸出樣例

輸入樣例#1:

 複製

3
3 1 2 3
3 1 2 5
6 1 2 3 5 4 6

輸出樣例#1: 複製

1
0
7

題解:說實話剛看到這道題目的第一反應是應該方案揹包(揹包問題傳送)有關吧,但又是怎樣有關的,毫無思路,後來轉念一想,這裡求的是集合中的一個數等於集合中任意兩個數的和,那這不就相當於這個數是揹包容量另外兩個數是放入揹包使揹包正好裝滿的兩個物品,所以問題解決了,不過這裡處理資料的時候,我們先讓揹包的容量等於集合中所有元素之和,然後取揹包容量集合中元素時的狀態相加即可。

import java.util.*;
/*
 *
 */
public class Main{
	public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        int n=in.nextInt();
        for(int i=1;i<=n;i++) {
        	int m=in.nextInt();
        	int[] a=new int[m+1];
        	int sum=0;
        	for(int j=1;j<=m;j++) {
        		a[j]=in.nextInt();
        		sum+=a[j];
        	}
        	Arrays.sort(a, 1,m+1);
        	int[] dp=new int[sum+1];
        	int res=0;
        	dp[0]=1;
        	for(int j=1;j<=m;j++) {
        		res+=dp[a[j]];
        		for(int k=sum;k>=a[j];k--) {
        			dp[k]+=dp[k-a[j]];
        		}
        	}
        	System.out.println(res);
        }
    }
}