深度優先搜尋 幸運的袋子

2021-08-28 14:32:08 字數 1096 閱讀 6606

分析:

1. 這是乙個組合問題,求可行方案的數目,因此無法用動態規劃。除了暴力搜尋,必須進行剪枝!

有幾個問題必須想清楚:

(1)為什麼要排序?而且還是從小到大排序?從大到小排序不行嗎?

回答:我們考慮是否要加入乙個新元素 y,假設前面已經選中了若干個數,這些數的和為 s, 乘積為 p。一般來說, s > 1 (因為都是正整數,s 必定》=1, 等於1的情況只有一種,就是前面只選了乙個數,而且這個數是1),若要為幸運袋,令 s + y > p * y,得到 y < s / (p-1),可知:如果我們按照公升序排列,當第 i 個數 a[i] 不滿足題意,即 y >= s / (p-1)時,後面的元素必定不滿足題意,因此可以得到本題最為重要的第乙個剪枝:如果搜尋到 a[i] 不滿足題意,後面直接 pass,即 break

(2)題目中說,相同號碼的球不作區分,如何避免重複計算?

回答:當搜尋到 a[i] 時,如果後面的若干個球的號碼與 a[i] 相同,則直接 pass !

/*

乙個袋子裡面有n個球,每個球上面都有乙個號碼(擁有相同號碼的球是無區別的)。如果乙個袋子是幸運的當且僅當所有球的號碼的和大於所有球的號碼的積。

例如:如果袋子裡面的球的號碼是,這個袋子就是幸運的,因為1 + 1 + 2 + 3 > 1 * 1 * 2 * 3

你可以適當從袋子裡移除一些球(可以移除0個,但是別移除完),要使移除後的袋子是幸運的。現在讓你程式設計計算一下你可以獲得的多少種不同的幸運的袋子。

分析:這個問題不是最優化問題,也不存在子問題重疊,因此無法用動態規劃和貪心

因此,可以用搜尋,為了快速程式設計,推薦用dfs,此時一定要好好考慮如何剪枝

*/#include#include#include#include#include#include#includeusing namespace std;

int const maxn = 1002;

int n,a[maxn];

int ans = 0; // 滿足條件的方法數目

int dfs(int a, int pos, long long sum, long long product)

return 0;

}

幸運的袋子

乙個袋子裡面有n個球,每個球上面都有乙個號碼 擁有相同號碼的球是無區別的 如果乙個袋子是幸運的當且僅當所有球的號碼的和大於所有球的號碼的積。例如 如果袋子裡面的球的號碼是,這個袋子就是幸運的,因為1 1 2 3 1 1 2 3 你可以適當從袋子裡移除一些球 可以移除0個,但是別移除完 要使移除後的袋...

幸運的袋子

乙個袋子裡面有n個球,每個球上面都有乙個號碼 擁有相同號碼的球是無區別的 如果乙個袋子是幸運的當且僅當所有球的號碼的和大於所有球的號碼的積。例如 如果袋子裡面的球的號碼是,這個袋子就是幸運的,因為1 1 2 3 1 1 2 3 你可以適當從袋子裡移除一些球 可以移除0個,但是別移除完 要使移除後的袋...

幸運的袋子

乙個袋子裡面有n個球,每個球上面都有乙個號碼 擁有相同號碼的球是無區別的 如果乙個袋子是幸運的當且僅當所有球的號碼的和大於所有球的號碼的積。例如 如果袋子裡面的球的號碼是,這個袋子就是幸運的,因為1 1 2 3 1 1 2 3 你可以適當從袋子裡移除一些球 可以移除0個,但是別移除完 要使移除後的袋...