poj 3977 折半列舉 二進位制列舉 二分

2021-06-21 12:28:22 字數 724 閱讀 1528

拿到這道題的時候就想到折半列舉+二分。首先想到的是講陣列分成折半成正負兩個陣列再進去二分查詢。想想就不對。

正確的方法應該是直接將陣列折半。然後遍歷另一半,尋找最近的和。

#include #include #include #include using namespace std;

#define inf 1000000000000000ll

#define ll long long

ll minn,sum;

ll a[40],k;

int n;

struct c

c[1<<18],s[1<<18];

bool cmp(c &a,c &b)

return r+1;

}ll abs(ll a) //必須自己寫。

void solve()

sort(c,c+(1s[k++]=c[i];

else if(c[i].sum==0&&s[k-1].sum==0&&s[k-1].num==0)

s[k++]=c[i]; //折半完成。

int len2=n-len;

for(int i=0;i< 1<>j&1)

ans+=a[len+j],num++;

ll id=lower_bound(-ans); //尋找與其最近的和。

for(ll j=(id-3>=0?id-3:0); j<(id+3

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