窮舉法:從數列中任意選取幾個數,相加能否得到m,C語言描述

參考《挑戰程序設計競賽算法和數據結構》

原始問題:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_5_A

當n的數目較少的時候,可將元素的所有組合都列舉出來,每個元素都有 “選” 和 “不選” 兩種情況,總共就有2^n種

思路:

假設輸入的M值爲8,可供選擇的數爲 【1、5、7】

調用①solve(0,8),i=0,m=8,①調用②③

①調用②solve(1,8)【不選擇第一個元素】,①調用③solve(1,8-1)【選擇第一個元素】

②調用④solve(2,8)【不選擇第二個元素】,②調用⑤solve(2,8-5)【選擇第二個元素】;③調用⑥solve(2,7)【不選擇第二個元素】,③調用⑦solve(2,7-5)【選擇第二個元素】;

.....

單純生成各種情況的二進制:如{0,0,0}、{1,1,1}、{1,0,1}等

#include<stdio.h>
int n=3,S[3],j;

void rec(int i){
	if(i==n){
		for(j=0;j<n;j++){
			printf("%d ",S[j]);
		}
		printf("\n");
		return;
	}
	rec(i+1);
	S[i]=1;
	rec(i+1);
	S[i] = 0;
} 

int main(){
	for(j=0;j<n;j++) S[j]=0;
	rec(0);
	return 0;
} 

完整程序:

#include<stdio.h>
int n, A[50];

//從輸入值m中,減去所選元素的遞歸函數 
int solve(int i,int m){
	if (m==0) return 1;
	if (i>=n) return 0;
	int res = solve(i+1,m) || solve(i+1,m-A[i]);
	return res;
}

int main(){
	int q,M,i;
	scanf("%d",&n);
	for(i=0;i<n;i++) scanf("%d",&A[i]); 
	scanf("%d",&q);
	for(i=0;i<q;i++){
		scanf("%d",&M);
		if(solve(0,M)) printf("yse\n");
		else printf("no\n");
	} 
	return 0;
} 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章