SRM 563 DIV1 本番

休日深夜のSRM。寒い

Coding

Easy (300)

適当に辞書順greedyやった。
しかしこの先できるか?の判定ミスってた。
greedyではランダムテストをすることにしているので、Submitしたあとテスト書いたら明らかに「この先できるか?」判定がおかしい。
ラスト10分程度になってからResubmitすることに決めて、書き始めて、なんか適当にやったらランダムテスト通ったのでResubmitした。
90.00ptになってしまった。

Medium (500)

適当に書いた区間DPが通ったのでSubmitした。252.75pt

Challenge

Easy、自分がミスしていたのもあって、みんな落ちそうだなーと思っていた。
そして、適当な人をランダムケースでChallengeしてみたら、成功した。
しかしそのあと、調子に乗って5人に読まずにChallengeしたところ、+100/-125 と、マイナスになってしまった。
やはり、連続の爆撃は、完全に読まずにではなく、「明らかなミスがぱっと見でわかる」状態でないとやるべきでないと思う。
最終的な順位への影響は、+50だったとしても10位あがったくらいだったが、この10位というのは大きいか小さいか?

結果

Easy: +90.00/300
Medium: 252.75/500
Challenge: 2/5 = -25
Division Place: 145/609
Rating: 14421540

コメント

まあ。
もう少し速く確実に解きたい。

コード

Easy

※不要なルーチンがある

#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <set>
#include <map>
#include <queue>
#include <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <cctype>
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i))
#define each(it,o) for(__typeof((o).begin()) it = (o).begin(); it != (o).end(); ++ it)
#define all(o) (o).begin(), (o).end()
#define mset(m,v) memset(m,v,sizeof(m))

using namespace std;
typedef vector<int> vi;  

int dp[55][55];
struct FoxAndHandle {
	string S, t, a, ss;
	bool rec(int i, int j) {
		if(dp[i][j] != -1) return dp[i][j];
		bool r = false;
		if(i == t.size()) {
			string e;
			string tt = t;
			reu(k, 0, j) {
				bool q = false;
				rep(l, tt.size()) if(tt[l] == S[k]) {
					tt[l] = ' ';
					q = true;
					break;
				}
				if(!q) e += S[k];
			}
			reu(k, j, S.size()) {
				bool q = false;
				rep(l, a.size()) if(a[l] == S[k]) {
					a[l] = ' ';
					q = true;
					break;
				}
				if(!q) e += S[k];
			}
			sort(all(e));
//			cout << e << ", " << ss << endl;
			r = true;
			if(e != ss) r = false;
//			rep(k, a.size()) if(a[k] != ' ') r = false;
		}else if(j == S.size()) ;
		else {
			if(t[i] == S[j]) r |= rec(i+1, j+1);
			r |= rec(i, j+1);
		}
		return dp[i][j] = r;
	}
	string lexSmallestName(string S_) {
		S = S_;
		map<char,int> m; each(i, S) m[*i] ++;
		string s;
		each(i, m) rep(j, i->second/2) s += i->first;
		sort(all(s)); ss = s;
		int n = s.size();
		vi b(n);
		string r = "";
		rep(i, n) {
			rep(j, n) if(!b[j]) {
				t = r; t += s[j];
				a = ""; rep(k, n) if(!b[k] && j != k) a += s[k];
				mset(dp, -1);
				if(rec(0, 0)) {
					r = t;
					b[j] = 1;
					break;
				}
			}
		}
		return r;
	}
};
Medium
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <set>
#include <map>
#include <queue>
#include <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <cctype>
#define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i))
#define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i))
#define mset(m,v) memset(m,v,sizeof(m))
#define INF 0x3f3f3f3f

using namespace std;
typedef vector<int> vi;

int dp1[111][111][55];
int dp2[111][111];
struct SpellCards {
	vi d, e; int n;
	int rec2(int l, int u) {
		if(dp2[l][u] != -1) return dp2[l][u];
		int r = -INF;
		if(l == u) r = 0;
		rer(i, l+1, u) {
			int x = rec(l+1, i, e[l%n]-1);
			if(x != -INF) r = max(r, d[l%n] + x + rec2(i, u));
		}
		return dp2[l][u] = r;
	}
	int rec(int l, int u, int k) {
		if(dp1[l][u][k] != -1) return dp1[l][u][k];
		int r = -INF;
		if(k == 0) r = 0;
		else reu(i, l, u) {
			r = max(r, rec2(l, i) + rec(i+1, u, k-1));
		}
		return dp1[l][u][k] = r;
	}
	int maxDamage(vector <int> level, vector <int> damage) {
		e = level, d = damage; n = e.size();
		int r = 0;
		mset(dp1, -1); mset(dp2, -1);
		reu(l, 0, n) rer(u, l+1, min(l+n, n*2)) r = max(r, rec2(l, u));
		return r;
	}
};