聰明的質監員

2022-05-04 22:45:13 字數 1443 閱讀 2948

字首和+二分答案的一道好題。

不難看出這個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...