AOJ 0281 Formation
問題
解く
最初簡単だろうと思って、貪欲法で解いたら、WA。
DPで解こうとするとMLEになる。
適当な人数になるまではCANにしとけばいいことに気づく。
cとaが小さくなるまでCANに割り振って、そこからDP,runtime error
数分悩む。1000 1000 3とかの場合に大変なことになりそうだったので
CANにつづいてCCA、CCCに割り振る。んでメモ化再帰。
runtime errorになったので配列の大きさを調節
AC
10回以上もsubmitしてすみません。
ちゃんとアルゴリズムを考えられるようになりたい
心臓に悪いコード
int Q; int dp[64][64][64]; int dfs(int c, int a, int n){ if(dp[c][a][n] >= 0) return dp[c][a][n]; int res = 0; if(c > 0 && a > 0 && n > 0) res = max(res, dfs(c-1, a-1, n-1)+1); if(c > 1 && a > 0) res = max(res, dfs(c-2, a-1, n)+1); if(c > 2) res = max(res, dfs(c-3, a, n)+1); return dp[c][a][n] = res; } int main(){ cin >> Q; rep(i, Q){ memset(dp, -1, sizeof(dp)); int c, a, n; cin >> c >> a >> n; int res = 0; while(c > 10 && a > 5 && n > 0){ res++; c--; a--; n--; } while(c > 10 && a > 5){ res++; c-=2; a--; } while(c > 10){ res++; c-=3; } res += dfs(c, a, n); printf("%d\n", res); } return 0; }