Particle

競技プログラミングについての雑記

AOJ 2337: ねこ鍋改造計画(仮)

解法

cuteでソートするとDPできて、cuteの最大値が定数で、dp[鍋の種類][重さ] := max{cuteの最小値}となるようなテーブルがO(NW)で作れる。
できたテーブルは尺取法でO(W)で走査できる。全体で、O(NW)

#include <iostream>
#include <algorithm>
#include <map>
#include <cstring>
using namespace std;
typedef pair<int, int> P;
typedef pair<int, P> PP;
#define fst first
#define snd second
#define chmax(X,Y) X=max(X,Y);
#define chmin(X,Y) X=min(X,Y);
#define N 1500
#define W 10010
int n[2], w, dp[2][W];
PP d[N];

int main(){
	cin>>n[0]>>n[1]>>w;
	for(int i = 0; i < 2; i++){
		for(int j = 0; j < n[i]; j++){
			int a, b;
			cin>>a>>b;
			d[n[0]*i+j] = PP(b, P(a, i));
		}
	}
	sort(d, d+n[0]+n[1]);
	int res = 1000000000;
	for(int i = 0; i < n[0]+n[1]; i++){
		int b = d[i].fst, a = d[i].snd.fst, t = d[i].snd.snd;
		for(int j = w; j > a; j--)
			chmax(dp[t][j], dp[t][j-a]);
		dp[t][a] = b;
		int pos[2] = {};
		for(int j = 0; j < 2; j++) while(++pos[j]<=w && !dp[j][pos[j]]);
		while(pos[0]<=w && pos[1]<=w){
			int wf = abs(pos[1]-pos[0]), cf = max(b-dp[0][pos[0]], b-dp[1][pos[1]]);
			chmin(res, max(wf, cf));
			if(wf<=cf){
				int s = dp[0][pos[0]]>dp[1][pos[1]];
				int r = dp[s][pos[s]];
				while(++pos[s]<=w && dp[s][pos[s]]<=r);
			} else {
				int s = pos[0]>pos[1];
				while(++pos[s]<=w && !dp[s][pos[s]]);
			}
		}
	}
	cout<<res<<endl;

	return 0;
}