試題 算法訓練 和爲T---藍橋杯

試題 算法訓練 和爲T

題目描述:

資源限制
時間限制:1.0s 內存限制:256.0MB
問題描述
  從一個大小爲n的整數集中選取一些元素,使得它們的和等於給定的值T。每個元素限選一次,不能一個都不選。
輸入格式
  第一行一個正整數n,表示整數集內元素的個數。
  第二行n個整數,用空格隔開。
  第三行一個整數T,表示要達到的和。
輸出格式
  輸出有若干行,每行輸出一組解,即所選取的數字,按照輸入中的順序排列。
  若有多組解,優先輸出不包含第n個整數的;若都包含或都不包含,優先輸出不包含第n-1個整數的,依次類推。
  最後一行輸出總方案數。
樣例輸入
5
-7 -3 -2 5 9
0
樣例輸出
-3 -2 5
-7 -2 9
2
數據規模和約定
  1<=n<=22
  T<=maxlongint
  集合中任意元素的和都不超過long的範圍
  
解題思路:
(如果大家不會動態規劃,可以看一下這個up主的視頻講解,絕對一次就懂非常清晰)

動態規劃講解,一次就懂

動態規劃(注意倒着遍歷,因爲題目要求若有多組解,優先輸出不包含第n個整數的;若都包含或都不包含,優先輸出不包含第n-1個整數的,依次類推)

從n的位置開始遍歷,每一個位置可以選擇也可以不選擇,有兩個狀態,但是優先不選擇的那一邊。還有注意代碼中展示的終止條件(爲什麼不只是t的值爲T且數組中有數值的時候輸出)

AC代碼:

#include <stdio.h>
long int a[30];
long int b[30];
long int T;
int n;
long int sum=0;
void f(int long t,int pos,int i )//i爲起始遍歷的索引位置 ,pos爲數組中符合答案的元素個數 
 {
	int j;
	if(t==T&&pos!=0&&i<1) 
	{ //終止條件 注意全部遍歷完再進行判斷(防止 -1 1 -2 2 3 -3的特例) 並且 不能不選
		sum++;//sum爲答案的個數 
		for(j=pos-1; j>=0; j--) //倒着遍歷輸出
			printf("%ld ",b[j]);
		printf("\n");
	} 
	else 
	{
		if(i<1)
			return ;//遍歷到數組第一項還未滿足t==T;則返回
			
		f(t,pos,i-1);
		
		b[pos]=a[i];
		f(t+a[i],pos+1,i-1);
	}
}
int main() 
{
	int i;
	scanf("%d",&n);
	for(i=1; i<=n; i++)
		scanf("%ld",&a[i]);
	scanf("%ld",&T);
	f(0,0,n);
	printf("%d\n",sum);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章