1. 程式人生 > >CODEVS 2144 砝碼稱重2

CODEVS 2144 砝碼稱重2

//二分dfs,最後合併 
#include<bits/stdc++.h>
using namespace std;
const int maxn = 400000; 
int n, m, tot1, tot2, a[31];
int ans = 0x3f3f3f3f;
struct node{
    int num, w;
} hash1[maxn], hash2[maxn];

bool cmp(node p, node q){
    return p.w < q.w;
}

void dfs1(int haoyu, int step, int mnow){
    if(haoyu > n/2
) return; hash1[++tot1].num = step + 1; hash1[tot1].w = mnow + a[haoyu]; //if(hash1[tot1].w == m) ans = hash1[tot1].num; dfs1(haoyu+1, step+1, mnow+a[haoyu]); dfs1(haoyu+1, step, mnow); } void dfs2(int haoyu, int step, int mnow){ if(haoyu > n) return; hash2[++tot2].num = step
+ 1; hash2[tot2].w = mnow + a[haoyu]; //if(hash2[tot2].w == m) ans = hash2[tot2].num; dfs2(haoyu+1, step+1, mnow+a[haoyu]); dfs2(haoyu+1, step, mnow); } int find(int x){//二分查詢程式碼要記牢,左開右閉 int l = 1, r = tot2+1, mid = l + (r-l)/2; while(l < r){ if(x < hash2[mid].w){ r = mid; mid = l + (r-l)/2
; } if(x > hash2[mid].w){ l = mid + 1; mid = l + (r-l)/2; } if(x == hash2[mid].w) return mid; } return -1; } int main(){ cin >> n >> m; for(int i = 1; i <= n; i++) cin >> a[i]; sort(a+1, a+n+1); dfs1(1, 0, 0); sort(hash1+1, hash1+tot1+1, cmp); dfs2(n/2+1, 0, 0); sort(hash2+1, hash2+tot2+1, cmp); for(int i = 0; i <= tot1; i++){//從0開始是因為有可能前半段沒有目標砝碼,全在後半段,如果從1開始就找不到後半段的了 int flag = find(m - hash1[i].w); if(flag != -1){ ans = min(hash1[i].num + hash2[flag].num, ans); } } cout << ans << endl; return 0; }