字首和+二分答案的一道好題。
不難看出這個w和礦石的重量是有關係的。礦石的重量的最大值和最小值可以記錄出來,這樣w便有界。根據題意w所在區間顯然可以單調,所以可以使用二分進行求解。
我們二分w,然後去計算以這個w為答案的值與標準值相比較。
二分的check函式用字首和維護就可以。通常的做法是開兩個陣列,乙個sumval記錄每個礦石價值的字首和,乙個sumnum記錄選取礦石數量的字首和。
為什麼選這兩個字首和?看公式啊,y值就是要用這兩個數算出來的。
我們列舉每乙個礦石,如果發現有乙個w[i] > w ,那麼sumval[i] = sumva[i-1] + v[i] , sumnum[i] = sumnum[i-1] + 1,否則sumval[i] = sumval[i-1] , sumnum[i] = sumnum[i-1]。
二分的時候順帶維護乙個ans,最後的答案就是了。
1 #include 2 #include 3 #include 4 #include 5#define maxn 200005
6 typedef long
long
ll;7
const ll linf = 1926081719260817;8
long
long
intread()
21 ll n,m,s,ans =linf;
22ll w[maxn],v[maxn];
23ll interval_left[maxn],interval_right[maxn];
24ll sumval[maxn],sumnum[maxn];
2526
ll lmax(ll x,ll y)
29ll labs(ll x)
32bool
check(ll mid)
41else45}
46for (register ll i=1;i<=m;i++)
47 val_y += (sumval[interval_right[i]] - sumval[interval_left[i]-1]) * (sumnum[interval_right[i]] - sumnum[interval_left[i]-1
]);48 ans = std::min(ans,labs(val_y -s));
49if (val_y >s)
50return
true;51
else
52return
false;53
54}5556
intmain()
63 r++;
64for (register ll i=1;i<=m;i++)
67while (l 74 printf("
%lld\n
",ans);
75return0;
76 }
聰明的質監員
noip2011 day2 t2 題目描述 小 t 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有n 個礦石,從1到n 逐一編號,每個礦石都有自己的重量wi 以及價值vi。檢驗礦產的流程是 見圖 若這批礦產的檢驗結果與所給標準值s 相差太多,就需要再去檢驗另一批礦產。小t不想費時間去檢驗...
聰明的質監員
本題是乙個比較明顯的二分題,顯然可以看出來這個標準值s是可以二分的,之後如果暴力o nmlog1e6 就是50分。但我們顯然不用暴力,這裡我們可以先預掃一遍陣列,並用字首和存w和v,之後再乙個o m 暴力判斷就可以了。和大於標準時加大l以加大mid,小於時減少r。並一定要注意l和r的初始大小,l為所...
聰明的質監員題解
原題 洛谷p1314 題解 這道題屬於典型的二分 w越小,y越大那麼就直接做就完事了唄。注意一下幾點 1.開long long 2.使用字首和,否則可能會超時 include using namespace std int n,m,w 200005 v 200005 l 200005 r 20000...