POJ 3977 折半列舉

2022-02-03 06:03:27 字數 931 閱讀 1838

如無法區分折半列舉,二分,這裡

這題我感覺出了是用列舉,畢竟資料範圍很小,但是,集合中每個元素都有可能被選或者不被選,根據計數原理應該會有\(2^-1\)種情況,需要刨除空集,列舉顯然是會t掉,那怎麼辦呢?

考慮選出來的集合有幾種情況,有可能都在前一半,有可能都在後一半,還有可能前後都有,前後都有的情況可以拆分成前兩種情況, 所以優先考慮前兩種,35的一半可以取17,發現\(2^\)是不會t的,我們只要每次列舉一半,然後就能解決這個問題,這就是如題所說的折半列舉。

使用上述方法可以解決前兩種情況,那前後都有呢?前後都有的必然是由前一半的乙個子集和後一半的乙個子集構成,因為要絕對值最小,所以要使這個集合接近於0,因此列舉前乙個集合的每個子集,然後找到乙個子集的和與這個子集的相反數最接近的集合,把他們當作答案就行。

這道題來說的話,感覺如果不知道折半列舉這種思想,做起來還是挺困難的 ,有的時候暴力並不是沒什麼用,畢竟人家的另乙個名字叫樸素演算法,也許有的時候想不出什麼高階資料結構,什麼轉移方程,不如寫個暴力看看,也許優化一下就能a,就算a不了也會有很多過程分吧,畢竟oi不像acm那樣只算ac的題目,也許10分就能拉開很大差距。

#include#include#include#include#define ll long long 

const int n=40;

using namespace std;

ll a[n],n;

pairans;

mapp;

map::iterator it;

ll abs(ll x)

void calc()

for(ll i=1;i<(1<<(n-n/2));i++)

} printf("%lld %lld\n",ans.first,ans.second);

} int main()

}

poj 3977 折半列舉

題目大意 給定n n 35 個數字,每個數字都 2 15.其中乙個或多個數字加和可以得到s,求出s的絕對值的最小值,並給出當s取絕對值最小值時,需要加和的數字的個數。題目分析 實現 c include include include include include include includeus...

POJ 3977 折半列舉

給你n個數,n最大35,讓你從中選幾個數,不能選0個,使它們和的絕對值最小,如果有一樣的,取個數最小的 子集個數共有2 n個,所以不能全部列舉,但是可以分為兩部分列舉 列舉一半的所有情況,然後後一半二分即可 1 include bits stdc h 2 define n 45 3using nam...

poj3977(折半列舉,多坑)

translation 給出一列數列,找出其中的非空連續子串行,使得其和的絕對值最小。如果有相同的和的情況下輸出元素個數最少的那個 solution 折半列舉即可 note 思路很簡單,分成兩半,折半列舉即可,但是 中有很多坑。首先必須對前後兩部分只選乙個的情況單獨考慮。然後如果 ans sum的預...