poj3977(折半列舉,多坑)

2021-07-24 14:14:21 字數 1186 閱讀 6783

/*

translation:

給出一列數列,找出其中的非空連續子串行,使得其和的絕對值最小。如果有相同的和的情況下輸出元素個數最少的那個

solution:

折半列舉即可

note:

#: 思路很簡單,分成兩半,折半列舉即可,但是**中有很多坑。首先必須對前後兩部分只選乙個的情況單獨考慮。然後如果

ans_sum的預設值為inf的話還是會wa,所以最好設定為隨便乙個集合的和就行。

date:

2016.11.12

*/#include #include #include #include #include using namespace std;

const int maxn = 36;

const int inf = 1e30;

typedef long long ll;

mapsum_set; //first:sum second:numbers of elements

ll a[maxn]; int n;

ll abs1(ll x)

int main()

}if(num == 0) continue;

if(abs1(ans_sum) > abs1(sum) || (abs1(ans_sum) == abs1(sum) && ans_cnt > num))

map::iterator it = sum_set.find(sum);

if(it != sum_set.end())else

} //列舉後半部分

for(int i = 0; i < (1 << bn); i++)

}if(num == 0) continue;

if(abs1(ans_sum) > abs1(sum) || (abs1(ans_sum) == abs1(sum) && ans_cnt > num))

//在已經預處理過的前半部分尋找最為接近sum的值

map::iterator it = sum_set.lower_bound(-sum);

if(it != sum_set.end())

}if(it != sum_set.begin())

}} cout << abs1(ans_sum) << " " << ans_cnt << endl;

}}

POJ 3977 折半列舉

如無法區分折半列舉,二分,這裡 這題我感覺出了是用列舉,畢竟資料範圍很小,但是,集合中每個元素都有可能被選或者不被選,根據計數原理應該會有 2 1 種情況,需要刨除空集,列舉顯然是會t掉,那怎麼辦呢?考慮選出來的集合有幾種情況,有可能都在前一半,有可能都在後一半,還有可能前後都有,前後都有的情況可以...

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...