Advertisement
Guest User

Untitled

a guest
Jun 30th, 2016
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.62 KB | None | 0 0
  1. // Problem D. Daruma Otoshi / ダルマ落とし
  2.  
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5.  
  6. auto solve(int n, const vector<int>& w) -> int {
  7. // 区間DP
  8. // dp[l][r] := (閉区間[l, r]における解)
  9. vector<vector<int>> dp(n, vector<int>(n, 0));
  10. // f(l, r) : l番目とr番目のブロックの重さの差が1以下なら2, それ以外なら0を返す
  11. auto f = [&w](int l, int r) {return abs(w[l] - w[r]) <= 1 ? 2 : 0;};
  12. // l番目からr番目の範囲で叩き出せるブロックの数の最大値
  13. // fm(l, r) : l+1番目からr-1番目のブロックがすべて叩き出されていていればl番目とr番目のブロックを叩き出す
  14. auto fm = [&](int l, int r) {return dp[l + 1][r - 1] + (dp[l + 1][r - 1] < r - l - 1 ? 0 : f(l, r));};
  15. // fl(l, r) : r-1番目とr番目のブロックを叩き出す
  16. auto fl = [&](int l, int r) {return dp[l][r - 2] + f(r - 1, r);};
  17. // fr(l, r) : l番目とr+1番目のブロックを叩き出す
  18. auto fr = [&](int l, int r) {return dp[l + 2][r] + f(l, l + 1);};
  19. // 区間長2のDPテーブルを埋める
  20. for(auto l = 0, r = l + 1; l < n - 1; l++, r++) dp[l][r] = f(l, r);
  21. // 短い区間から順にDPテーブルを更新
  22. for(auto len = 3; len < n; len += 2)
  23. for(auto l = 0, r = l + len; l < n - len; l++, r++)
  24. dp[l][r] = max({dp[l][r], fm(l, r), fl(l, r), fr(l, r)});
  25. // nが偶数ならdp[0][n - 1], 奇数ならdp[0][n - 2]かdp[1][n - 1]
  26. return max({dp[0][n - 1], dp[0][n - 2], dp[1][n - 1]});
  27. }
  28.  
  29. auto main() -> int {
  30. int n;
  31. while(cin >> n, n) {
  32. vector<int> w(n);
  33. for(auto& i : w) cin >> i;
  34. cout << solve(n, w) << endl;
  35. }
  36. return 0;
  37. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement