Codeforces 18 D. Seller Bob
問題
Bobはn日間メモリの商売をする。
n日目の行動は以下の形式で与えられる。
Bobはメモリを同時に一つしか持てず、客がちょうど欲しがるサイズのメモリしか売ることが出来ない。
2^xMBのメモリを売ると、2^xドルの利益が出る。
Bobの得られる最大の利益を求めよ。
制約条件
n≦5000
x≦2000
方針
動的計画法による。
dp[i]をi日目まででBobが出せる最大の利益とする。
i日目に2^xMBのメモリを求める客が来るとすると、
2^xMBのメモリを最後に入手した日をpos[x]日目として、
dp[i]=max(dp[i-1],dp[pos[x] ]+2^x)と書ける。
この漸化式に従い、テーブルを更新していけばO(n)で答えが求まる。
答えは大きいのでBigIntegerを使う必要がある。
ソースコード
public class CF18D { public static void main(String args[]) { new CF18D().run(); } void run() { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] pos = new int[2001]; for(int i = 0; i < 2001; i++) pos[i] = -1; BigInteger[] dp = new BigInteger[n+1]; dp[0] = BigInteger.ZERO; for(int i = 1; i <= n; i++){ String s = sc.next(); int x; x = sc.nextInt(); dp[i] = dp[i-1]; if(s.compareTo("win") == 0) pos[x] = i; else{ if(pos[x] >= 0 && dp[i].compareTo(dp[pos[x]].add(BigInteger.ONE.shiftLeft(x))) < 0) dp[i] = dp[pos[x]].add(BigInteger.ONE.shiftLeft(x)); } } System.out.println(dp[n]); } }