P2089 烤雞 【枚舉】【深搜】

題目

題目描述

豬豬Hanke特別喜歡喫烤雞(本是同畜牲,相煎何太急!)Hanke喫雞很特別,爲什麼特別呢?因爲他有10種配料(芥末、孜然等),每種配料可以放1—3克,任意烤雞的美味程度爲所有配料質量之和

現在,Hanke想要知道,如果給你一個美味程度,請輸出這10種配料的所有搭配方案

輸入格式

一行,n<=5000

輸出格式

第一行,方案總數

第二行至結束,10個數,表示每種配料所放的質量

按字典序排列。

如果沒有符合要求的方法,就只要在第一行輸出一個“0”

解析

正解直接暴力枚舉。只不過代碼不太好看的亞子。(或許不需要這麼多大括號。。。)

int main()
{
	int n;
	cin >> n;
	if( n > 3 * 10  || n < 1 * 10) 
	{
		cout << 0 << endl;
		return 0;	
	}   
	int ans = 0;
	for(int i1 = 1 ; i1 <= 3 ; i1 ++)
	{
		for(int i2 = 1 ; i2 <= 3 ; i2 ++)
		{
			for(int i3 = 1 ; i3 <= 3 ; i3 ++)
			{
				for(int i4 = 1 ; i4 <= 3 ; i4 ++)
				{
					for(int i5 = 1 ; i5 <= 3 ; i5 ++)
					{
						for(int i6 = 1 ; i6 <= 3 ; i6 ++)
						{
							for(int i7 = 1 ; i7 <= 3 ; i7 ++)
							{
								for(int i8 = 1 ; i8 <= 3 ; i8 ++)
								{
									for(int i9 = 1 ; i9 <= 3 ; i9 ++)
									{
										int i10 = n - i1 - i2 - i3 - i4 -i5 - i6 - i7 - i8 - i9;
										if(i10 <= 0 || i10 >3) continue;
										ans ++;
									
									}
								}
							}
						}
					}
				}
			}
		}
	}
	cout << ans << endl;
	for(int i1 = 1 ; i1 <= 3 ; i1 ++)
	{
		for(int i2 = 1 ; i2 <= 3 ; i2 ++)
		{
			for(int i3 = 1 ; i3 <= 3 ; i3 ++)
			{
				for(int i4 = 1 ; i4 <= 3 ; i4 ++)
				{
					for(int i5 = 1 ; i5 <= 3 ; i5 ++)
					{
						for(int i6 = 1 ; i6 <= 3 ; i6 ++)
						{
							for(int i7 = 1 ; i7 <= 3 ; i7 ++)
							{
								for(int i8 = 1 ; i8 <= 3 ; i8 ++)
								{
									for(int i9 = 1 ; i9 <= 3 ; i9 ++)
									{
										int i10 = n - i1 - i2 - i3 - i4 -i5 - i6 - i7 - i8 - i9;
										if(i10 <= 0 || i10 >3) continue;
									//	ans ++;
										cout << i1 << " " << i2 << " " << i3 << " " << i4 << " "
											<< i5 << " " << i6 << " " << i7 << " " << i8 << " " 
											<< i9 << " " << i10 << endl;
									}
								}
							}
						}
					}
				}
			}
		}
	}

}

其實也可以使用宏定義:

#define f(x) for(i[x]=1;i[x]<=3;i[x]++)

 

如果使用深搜,而你只想用一個二維數組來表示,並且這個二維數組的第一列你又都要用來表示這個方法是否可行時,千萬不要忘記函數在回溯時,沒有回溯到的地方是沒有數值的。。。這就是爲什麼要多一個memcpy的拷貝操作。

int cnt = 0;
int ans[10005][11];

int dfs(int cur , int left)
{
	if(cur == 10)
	{
		if(left >= 1 && left <= 3)
		{
			ans[cnt][cur] = left;
			ans[cnt][0] = 1;
			cnt ++;
			memcpy(ans[cnt] , ans[cnt - 1] , 10 * sizeof(int));
			return 1;
		}
	}
	
	if(left < (10 - cur + 1) || left > (10 - cur + 1) * 3) return 0;

	for(int i = 1; i <= 3 ; i ++ )
	{
		ans[cnt][cur] = i;
		dfs(cur + 1 , left - i);
	}
}

int main()
{
	int n ;
	cin >> n;
	if( n < 10 || n > 30) 
	{
		cout << 0 << endl;
		return 0;
	}
	memset(ans , 0 , sizeof(ans));
	
	dfs(1 , n);
	
	cout << cnt << endl;
	for(int i = 0 ; i < cnt ; i++)
	{
		if(ans[i][0])
		{
		//	cout << i << " -- " <<  ans[i][0] << " : " ;
			for(int j = 1; j <= 10 ; j ++)
				cout << ans[i][j] << " ";
			cout << endl;
		}
	}
	
}

如果不選擇作死,還是比較順利的。

int ans1[11];
int ans2[10005][11];
int dfs(int cur , int left)
{
	if(cur == 10)
	{
		if(left >= 1 && left <= 3)
		{
			
			ans1[cur] = left;
			for(int i = 1; i <=10 ; i++)
				ans2[cnt][i] = ans1[i];
			cnt ++;
			return 0;
		}
	}
	for(int i = 1; i <= 3 ; i ++)
	{
		if(left < (10 - cur + 1) || left > 3 * (10 - cur + 1))
			continue;
		
		ans1[cur] = i; 
		dfs(cur + 1, left - i );
	}
}

 

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