TopCoder SRM 601 Div1 Easy WinterAndPresents
問題
n個のかばんがあって、i番目のかばんにはりんごがapple[i]個とみかんがorange[i]個入っている。
ここから次のようにしてりんごとみかんを取り出す。取り出し方は何通りあるか。
自然数Xを選ぶ。
それぞれのかばんから、りんごとみかんの合計がX個になるようにりんごとみかんを取り出す。
これを全てのかばんについて行い、りんごとみかんの個数のそれぞれの合計をa, bとする。
a, bの組が異なるとき、二つの取り出し方は異なると数える。
制約条件
n≦50
apple[i], orange[i]≦100万
方針
Xを固定。
すると、りんごとみかんの合計はnX個と決まる。
このうちいくつをりんごにできるか考える。
i番目の袋でりんごがa個とb個(a < b)に出来るとすると、
その袋ではa≦j≦bなるjなら、どのjでもりんごをj個にすることができる。
なので、それぞれの袋についてりんごの数の上限と下限を求め、
それを全て足してやれば全体のりんごの数の上限と下限が求まり、
間の数も全て作れることがわかる。
これを全てのXについて試せばいい。
ソースコード
class WinterAndPresents { public: long long getNumber(vector <int> apple, vector <int> orange) { int n = apple.size(); ll ans = 0; for(int x = 1; x <= 2000000; x++){ int lo = 0, hi = 0; rep(i, n){ if(apple[i] + orange[i] < x) goto FAIL; hi += min(apple[i], x); lo += max(0, x - orange[i]); } ans += hi - lo + 1; FAIL:; } return ans; } };