ddf2358d33 2012-08-08 kinaba: #include <iostream> ddf2358d33 2012-08-08 kinaba: #include <sstream> ddf2358d33 2012-08-08 kinaba: #include <iomanip> ddf2358d33 2012-08-08 kinaba: #include <vector> ddf2358d33 2012-08-08 kinaba: #include <string> ddf2358d33 2012-08-08 kinaba: #include <map> ddf2358d33 2012-08-08 kinaba: #include <set> ddf2358d33 2012-08-08 kinaba: #include <algorithm> ddf2358d33 2012-08-08 kinaba: #include <numeric> ddf2358d33 2012-08-08 kinaba: #include <iterator> ddf2358d33 2012-08-08 kinaba: #include <functional> ddf2358d33 2012-08-08 kinaba: #include <complex> ddf2358d33 2012-08-08 kinaba: #include <queue> ddf2358d33 2012-08-08 kinaba: #include <stack> ddf2358d33 2012-08-08 kinaba: #include <cmath> ddf2358d33 2012-08-08 kinaba: #include <cassert> ddf2358d33 2012-08-08 kinaba: using namespace std; ddf2358d33 2012-08-08 kinaba: typedef long long LL; ddf2358d33 2012-08-08 kinaba: typedef long double LD; ddf2358d33 2012-08-08 kinaba: typedef complex<LD> CMP; ddf2358d33 2012-08-08 kinaba: ddf2358d33 2012-08-08 kinaba: template<typename T> ddf2358d33 2012-08-08 kinaba: struct DP3 ddf2358d33 2012-08-08 kinaba: { ddf2358d33 2012-08-08 kinaba: int N1, N2, N3; ddf2358d33 2012-08-08 kinaba: vector<T> data; ddf2358d33 2012-08-08 kinaba: DP3(int N1, int N2, int N3, const T& t = T()) ddf2358d33 2012-08-08 kinaba: : N1(N1), N2(N2), N3(N3), data(N1*N2*N3, t) { assert(data.size()*sizeof(T)<(1<<26)); } ddf2358d33 2012-08-08 kinaba: T& operator()(int i1, int i2, int i3) ddf2358d33 2012-08-08 kinaba: { return data[ ((i1*N2)+i2)*N3+i3 ]; } ddf2358d33 2012-08-08 kinaba: void swap(DP3& rhs) ddf2358d33 2012-08-08 kinaba: { data.swap(rhs.data); } ddf2358d33 2012-08-08 kinaba: }; ddf2358d33 2012-08-08 kinaba: ddf2358d33 2012-08-08 kinaba: struct cmp { ddf2358d33 2012-08-08 kinaba: int N; ddf2358d33 2012-08-08 kinaba: cmp(int N):N(N){} ddf2358d33 2012-08-08 kinaba: bool operator()(int a, int b) const ddf2358d33 2012-08-08 kinaba: { ddf2358d33 2012-08-08 kinaba: if( abs(2*a - N*N) != abs(2*b - N*N) ) ddf2358d33 2012-08-08 kinaba: return abs(2*a - N*N) < abs(2*b - N*N); ddf2358d33 2012-08-08 kinaba: return a < b; ddf2358d33 2012-08-08 kinaba: } ddf2358d33 2012-08-08 kinaba: }; ddf2358d33 2012-08-08 kinaba: class KingdomAndDice { public: ddf2358d33 2012-08-08 kinaba: double newFairness(vector <int> firstDie, vector <int> secondDie, int X) ddf2358d33 2012-08-08 kinaba: { ddf2358d33 2012-08-08 kinaba: int N = firstDie.size(); ddf2358d33 2012-08-08 kinaba: sort(secondDie.begin(), secondDie.end()); ddf2358d33 2012-08-08 kinaba: ddf2358d33 2012-08-08 kinaba: vector<int> choice; ddf2358d33 2012-08-08 kinaba: { ddf2358d33 2012-08-08 kinaba: choice.push_back(N); ddf2358d33 2012-08-08 kinaba: for(int i=0; i+1<N; ++i) ddf2358d33 2012-08-08 kinaba: choice.push_back(secondDie[i+1]-secondDie[i]-1); ddf2358d33 2012-08-08 kinaba: choice.push_back(X-secondDie.back()); ddf2358d33 2012-08-08 kinaba: } ddf2358d33 2012-08-08 kinaba: int base = 0; ddf2358d33 2012-08-08 kinaba: { ddf2358d33 2012-08-08 kinaba: for(int k=0; k<N; ++k) ddf2358d33 2012-08-08 kinaba: if( firstDie[k]!=0 && firstDie[k]<secondDie[0] ) { ddf2358d33 2012-08-08 kinaba: choice[0] --; ddf2358d33 2012-08-08 kinaba: base += 0; ddf2358d33 2012-08-08 kinaba: } ddf2358d33 2012-08-08 kinaba: for(int i=0; i+1<N; ++i) ddf2358d33 2012-08-08 kinaba: for(int k=0; k<N; ++k) ddf2358d33 2012-08-08 kinaba: if( firstDie[k]!=0 && secondDie[i]<firstDie[k] && firstDie[k]<secondDie[i+1] ) { ddf2358d33 2012-08-08 kinaba: choice[i+1] --; ddf2358d33 2012-08-08 kinaba: base += i+1; ddf2358d33 2012-08-08 kinaba: } ddf2358d33 2012-08-08 kinaba: for(int k=0; k<N; ++k) ddf2358d33 2012-08-08 kinaba: if( firstDie[k]!=0 && secondDie[N-1]<firstDie[k] ) { ddf2358d33 2012-08-08 kinaba: choice[N] --; ddf2358d33 2012-08-08 kinaba: base += N; ddf2358d33 2012-08-08 kinaba: } ddf2358d33 2012-08-08 kinaba: } ddf2358d33 2012-08-08 kinaba: return solve(N, base, choice, count(firstDie.begin(), firstDie.end(), 0)); ddf2358d33 2012-08-08 kinaba: } ddf2358d33 2012-08-08 kinaba: ddf2358d33 2012-08-08 kinaba: double solve(int N, int base, const vector<int>& choice, int K) ddf2358d33 2012-08-08 kinaba: { ddf2358d33 2012-08-08 kinaba: DP3<int> dp(N+1, K+1, N*N+1); ddf2358d33 2012-08-08 kinaba: for(int i=0; i<=N; ++i) ddf2358d33 2012-08-08 kinaba: for(int p=0; p<=K; ++p) ddf2358d33 2012-08-08 kinaba: for(int sum=0; sum<=N*N; ++sum) ddf2358d33 2012-08-08 kinaba: { ddf2358d33 2012-08-08 kinaba: if(i==0) ddf2358d33 2012-08-08 kinaba: { ddf2358d33 2012-08-08 kinaba: dp(i,p,sum) = (sum==base && p<=choice[i]); ddf2358d33 2012-08-08 kinaba: } ddf2358d33 2012-08-08 kinaba: else ddf2358d33 2012-08-08 kinaba: { ddf2358d33 2012-08-08 kinaba: bool b = false; ddf2358d33 2012-08-08 kinaba: for(int z=0; z<=p && z<=choice[i]; ++z) ddf2358d33 2012-08-08 kinaba: if(sum>=i*z) ddf2358d33 2012-08-08 kinaba: b = b | dp(i-1,p-z,sum-i*z); ddf2358d33 2012-08-08 kinaba: dp(i,p,sum) = b; ddf2358d33 2012-08-08 kinaba: } ddf2358d33 2012-08-08 kinaba: } ddf2358d33 2012-08-08 kinaba: ddf2358d33 2012-08-08 kinaba: vector<int> cand; ddf2358d33 2012-08-08 kinaba: for(int sum=0; sum<=N*N; ++sum) ddf2358d33 2012-08-08 kinaba: if( dp(N,K,sum) ) ddf2358d33 2012-08-08 kinaba: cand.push_back( sum ); ddf2358d33 2012-08-08 kinaba: return *min_element(cand.begin(), cand.end(), cmp(N)) / double(N*N); ddf2358d33 2012-08-08 kinaba: } ddf2358d33 2012-08-08 kinaba: }; ddf2358d33 2012-08-08 kinaba: ddf2358d33 2012-08-08 kinaba: // BEGIN CUT HERE ddf2358d33 2012-08-08 kinaba: #include <ctime> ddf2358d33 2012-08-08 kinaba: double start_time; string timer() ddf2358d33 2012-08-08 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } ddf2358d33 2012-08-08 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) ddf2358d33 2012-08-08 kinaba: { os << "{ "; ddf2358d33 2012-08-08 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) ddf2358d33 2012-08-08 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } ddf2358d33 2012-08-08 kinaba: void verify_case(const double& Expected, const double& Received) { ddf2358d33 2012-08-08 kinaba: bool ok = (abs(Expected - Received) < 1e-9); ddf2358d33 2012-08-08 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; ddf2358d33 2012-08-08 kinaba: cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } ddf2358d33 2012-08-08 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); ddf2358d33 2012-08-08 kinaba: #define END verify_case(_, KingdomAndDice().newFairness(firstDie, secondDie, X));} ddf2358d33 2012-08-08 kinaba: int main(){ ddf2358d33 2012-08-08 kinaba: ddf2358d33 2012-08-08 kinaba: CASE(0) ddf2358d33 2012-08-08 kinaba: int firstDie_[] = {0, 2, 7, 0}; ddf2358d33 2012-08-08 kinaba: vector <int> firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); ddf2358d33 2012-08-08 kinaba: int secondDie_[] = {6, 3, 8, 10}; ddf2358d33 2012-08-08 kinaba: vector <int> secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); ddf2358d33 2012-08-08 kinaba: int X = 12; ddf2358d33 2012-08-08 kinaba: double _ = 0.4375; ddf2358d33 2012-08-08 kinaba: END ddf2358d33 2012-08-08 kinaba: CASE(1) ddf2358d33 2012-08-08 kinaba: int firstDie_[] = {0, 2, 7, 0}; ddf2358d33 2012-08-08 kinaba: vector <int> firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); ddf2358d33 2012-08-08 kinaba: int secondDie_[] = {6, 3, 8, 10}; ddf2358d33 2012-08-08 kinaba: vector <int> secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); ddf2358d33 2012-08-08 kinaba: int X = 10; ddf2358d33 2012-08-08 kinaba: double _ = 0.375; ddf2358d33 2012-08-08 kinaba: END ddf2358d33 2012-08-08 kinaba: CASE(2) ddf2358d33 2012-08-08 kinaba: int firstDie_[] = {0, 0}; ddf2358d33 2012-08-08 kinaba: vector <int> firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); ddf2358d33 2012-08-08 kinaba: int secondDie_[] = {5, 8}; ddf2358d33 2012-08-08 kinaba: vector <int> secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); ddf2358d33 2012-08-08 kinaba: int X = 47; ddf2358d33 2012-08-08 kinaba: double _ = 0.5; ddf2358d33 2012-08-08 kinaba: END ddf2358d33 2012-08-08 kinaba: CASE(3) ddf2358d33 2012-08-08 kinaba: int firstDie_[] = {19, 50, 4}; ddf2358d33 2012-08-08 kinaba: vector <int> firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); ddf2358d33 2012-08-08 kinaba: int secondDie_[] = {26, 100, 37}; ddf2358d33 2012-08-08 kinaba: vector <int> secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); ddf2358d33 2012-08-08 kinaba: int X = 1000; ddf2358d33 2012-08-08 kinaba: double _ = 0.2222222222222222; ddf2358d33 2012-08-08 kinaba: END ddf2358d33 2012-08-08 kinaba: CASE(4) ddf2358d33 2012-08-08 kinaba: int firstDie_[] = {6371, 0, 6256, 1852, 0, 0, 6317, 3004, 5218, 9012}; ddf2358d33 2012-08-08 kinaba: vector <int> firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); ddf2358d33 2012-08-08 kinaba: int secondDie_[] = {1557, 6318, 1560, 4519, 2012, 6316, 6315, 1559, 8215, 1561}; ddf2358d33 2012-08-08 kinaba: vector <int> secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); ddf2358d33 2012-08-08 kinaba: int X = 10000; ddf2358d33 2012-08-08 kinaba: double _ = 0.49; ddf2358d33 2012-08-08 kinaba: END ddf2358d33 2012-08-08 kinaba: CASE(5) ddf2358d33 2012-08-08 kinaba: int firstDie_[] = {278130165,933636493,607327308,19369203,439158229,445295066,370731340,551180273,163280323,359800317,834663837,108871632,362106962,921853660,145507840,284869553,246938492,379648759,956330140,525562675,251028940,270135098,862786589,513909283,412651940,499422899,724171306,922270222,938213346,61418124,248820926,891527589,812074952,155495258,23280465,761818758,328244247,975585791,108105856,414583437,424242761,168720992,585728188,0,0,0,0,0,0,0}; ddf2358d33 2012-08-08 kinaba: vector <int> firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); ddf2358d33 2012-08-08 kinaba: int secondDie_[] = {475017760,773630717,985005264,963668637,320647204,665487259,585555327,272107932,203172682,57845645,311126817,496577583,834654861,77335024,405827438,231342594,943378345,971851607,455697802,119475931,551079372,838525393,192593102,990828850,382044077,590561977,229071016,962163538,621629435,727621063,109926457,152882146,9199017,615779540,160320904,216276208,675743894,414050471,126645085,238141513,151262148,280509327,923103663,125699296,790073355,738597671,864455279,384833125,510401421,219630179}; ddf2358d33 2012-08-08 kinaba: vector <int> secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); ddf2358d33 2012-08-08 kinaba: int X = 1000000000; ddf2358d33 2012-08-08 kinaba: double _ = 0.5; ddf2358d33 2012-08-08 kinaba: END ddf2358d33 2012-08-08 kinaba: CASE(6) ddf2358d33 2012-08-08 kinaba: int firstDie_[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; ddf2358d33 2012-08-08 kinaba: vector <int> firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); ddf2358d33 2012-08-08 kinaba: int secondDie_[] = {475017760,773630717,985005264,963668637,320647204,665487259,585555327,272107932,203172682,57845645,311126817,496577583,834654861,77335024,405827438,231342594,943378345,971851607,455697802,119475931,551079372,838525393,192593102,990828850,382044077,590561977,229071016,962163538,621629435,727621063,109926457,152882146,9199017,615779540,160320904,216276208,675743894,414050471,126645085,238141513,151262148,280509327,923103663,125699296,790073355,738597671,864455279,384833125,510401421,219630179}; ddf2358d33 2012-08-08 kinaba: vector <int> secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); ddf2358d33 2012-08-08 kinaba: int X = 1000000000; ddf2358d33 2012-08-08 kinaba: double _ = 0.5; ddf2358d33 2012-08-08 kinaba: END ddf2358d33 2012-08-08 kinaba: CASE(6) ddf2358d33 2012-08-08 kinaba: int firstDie_[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; ddf2358d33 2012-08-08 kinaba: vector <int> firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); ddf2358d33 2012-08-08 kinaba: int secondDie_[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50}; ddf2358d33 2012-08-08 kinaba: vector <int> secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); ddf2358d33 2012-08-08 kinaba: int X = 100; ddf2358d33 2012-08-08 kinaba: double _ = 0.5; ddf2358d33 2012-08-08 kinaba: END ddf2358d33 2012-08-08 kinaba: CASE(7) ddf2358d33 2012-08-08 kinaba: int firstDie_[] = {0,0}; ddf2358d33 2012-08-08 kinaba: vector <int> firstDie(firstDie_, firstDie_+sizeof(firstDie_)/sizeof(*firstDie_)); ddf2358d33 2012-08-08 kinaba: int secondDie_[] = {1,2}; ddf2358d33 2012-08-08 kinaba: vector <int> secondDie(secondDie_, secondDie_+sizeof(secondDie_)/sizeof(*secondDie_)); ddf2358d33 2012-08-08 kinaba: int X = 4; ddf2358d33 2012-08-08 kinaba: double _ = 1; ddf2358d33 2012-08-08 kinaba: END ddf2358d33 2012-08-08 kinaba: ddf2358d33 2012-08-08 kinaba: } ddf2358d33 2012-08-08 kinaba: // END CUT HERE