TopCoder SRM 450 Div1 Medium StrongEconomy

問題

ターン制のゲームがある。
最初n個の工場とk人の職人がいて、毎ターンの最初にn*kのお金が入る。
priceのお金でターン終了時に工場を1つ建てるまたは職人を一人雇うことができる。
これはお金がある限り1ターンに何回でも行える。

targetのお金を稼ぐのにかかる最小ターン数を求めよ。

制約条件

n,k,price,target≦10^12

方針

シミュレーション。
1回ごとに、その状態でtargetまでのお金を稼ぐのにかかるターンを計算してそこからの最適解を求め、priceまでのお金を稼ぐのにかかるターンを計算して、
そこまでターンを進める。


priceのお金を稼いだら、工場と職人のうち、少ないほうを増やせばよい。
これを適当な回数(100万回くらい)繰り返せば最適解が求まる。

ソースコード

class StrongEconomy {
	public:
	long long earn(long long n, long long k, long long price, long long target) 
	{
		ll ans=1ll<<60, turn=0, money=0;
		rep(it,1000000){
			if(n*0.9*k>target){
				ans=min(ans,turn+1);
				break;
			}
			else{
				ll t=max(1ll,(target-money+n*k-1)/(n*k));
				ans=min(ans,turn+t);
			}
			ll t=(price-money+n*k-1)/(n*k);
			money+=t*n*k;
			ll d=money/price;
			if(abs(n-k)>d){
				if(n<k)n+=d;
				else k+=d;
			}
			else{
				int mod=(n+k+d)%2;
				n=(n+k+d)/2;
				k=n+mod;
			}
			money-=d*price;
			turn+=t;
		}
		return ans;
	}
};