日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

幸运袋子(详解)

發布時間:2024/7/23 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 幸运袋子(详解) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目分析

??一個袋子里面有n個球,每個球上面都有一個號碼(擁有相同號碼的球是無區別的)。如果一個袋子是幸運的當且僅當所有球的號碼的和大于所有球的號碼的積。
例如:如果袋子里面的球的號碼是{1, 1, 2, 3},這個袋子就是幸運的,因為1 + 1 + 2 + 3 > 1 * 1 * 2 * 3
??你可以適當從袋子里移除一些球(可以移除0個,但是別移除完),要使移除后的袋子是幸運的。現在讓你編程計算一下你可以獲得的多少種不同的幸運的袋子。

解題思路

??這道題的本質是在集合中找出符合條件的子集。
??對于兩個任意正整數a,b來說,如果a+b<ab,則必須有一個數為1,可以用數論來證明,這里不再贅述。
??推廣到任意k個正整數,假設a1,a2,…ak,如果不滿足條件,即sum<=multi,如果再選一個數使sum+b > multib,這個b一定是1,相反,如果選擇的b>1,則sum+b < multi*b,那么a1,a2,…ak,b就不滿足給定的條件。
??所以要將這些球進行升序排序。每次從小到大選擇,當選擇到a1,a2,…ak-1時滿足給定條件,再增加ak是不滿足條件,那么ak必然要大于等于之前的最大值,如果繼續向后選擇更大的數,必然無法滿足給定條件。
??如果有多個1,并且k=1使不滿足條件,但是下一個元素仍為1,就可以滿足條件,所以當位置吐過是1,雖然不滿足條件,但是應該繼續向后搜索,因為仍然有可能滿足條件。
對于重復的數字,組合只能算一個,所以要跳過這個數字,也就是去重

代碼實現(必要的地方有注釋)

#include <iostream> #include <algorithm> #include <vector>using namespace std;int getLuckBox(vector<int> x, size_t n, size_t pos, int sum, int multi) {int count = 0;for (size_t i = pos; i < n; ++i){sum += x[i];multi *= x[i];if (sum > multi){//如果當前位置可以滿足要求,就繼續從下一個位置開始count += 1 + getLuckBox(x, n, i + 1, sum, multi);}else if (x[i] == 1){//如果這個位置是1并且不滿足,可以從下一個位置嘗試count += getLuckBox(x, n, i + 1, sum, multi);}else{//如果當前位置不滿足,那么之后更大的數字也不可能滿足,直接直接返回,不再查找break;}//在搜索下一個位置前,要先恢復sum和multisum -= x[i];multi /= x[i];//如果喝下一個位置一樣,就直接跳過,不能有重復while (i < n - 1 && x[i] == x[i + 1]){++i;}}return count; }int main() {size_t n;while (cin >> n){vector<int> x;for (size_t i = 0; i < n; ++i){int tmp;cin >> tmp;x.push_back(tmp);}//按升序排序sort(x.begin(), x.end());cout << getLuckBox(x, n, 0, 0, 1);}return 0; }

總結

以上是生活随笔為你收集整理的幸运袋子(详解)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。