Problem:
Problem I:
Memory Match
Memory match is a single-player game which employs a set of 2
M
cards. Each card is labeled with a
number between 1 and
M
on its face. For each number
i
(1 ≤
i
≤
M
), there are exactly two cards which
have the number
i
. At the start of the game, all cards are shuffled and laid face down on a table. In each
turn you choose two cards and turn them face up. If two numbers on the cards are the same, they are
removed from the table. Otherwise, they are turned face down again (this is called a mismatch). When
you choose cards, you do not have to turn two cards simultaneously; you can choose the second card
after you see the number of the first card. The objective of the game is to remove all the cards with as
few mismatches as possible.
Royce A. Mitchell has extraordinary memory, so he can remember all the positions and the numbers of
the cards that he has already turned face up. Your task is to write a program that calculates the expected
number of mismatches, on average, when he plays the game optimally.
Input
The input consists of multiple datasets.
Each dataset consists of one even number
N
(2 ≤
N
≤ 1000) which denotes the number of cards in the
set.
The end of input is indicated by a line that contains a single zero. This is not part of the input and you
may not treat this line as a dataset.
Output
For each dataset, print the expected number of mismatches. Each output value may have an arbitrary
number of fractional digits, provided that the error is within 10
-6
.
Sample Input
2
4
6
8
10
52
0
Output for the Sample Input
0.0000000000
0.6666666667
1.3333333333
1.9238095238
2.5523809524
15.4435236099

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;

typedef long long ll;

int main(){
  cout<<fixed<<setprecision(12);
  ll n;
  while(cin>>n && n){
  vector<vector<double>> dp(1000,vector<double>(1000,0));
  double ans=0;
  dp[n/2][0]=1;
  for(ll i=n/2;i>0;i--){
    for(ll t=0;t<=i;t++){
      double k=dp[i][t];
      if(k==0){continue;}
      ll A=i*2-t;
      k*=t;
      k/=A;
      dp[i-1][t-1]+=k;
      k=dp[i][t]-k;
      if(k==0){continue;}
      A--;
      dp[i-1][t]+=k/A;
      k-=k/A;
      if(k==0){continue;}
      double d;
      d=k*(i*2-t*2-2)/(i*2-t-2);
      ans+=d;
      dp[i][t+2]+=d;
      d=k*t/(i*2-t-2);
      ans+=d;
      dp[i-1][t]+=d;
    }
  }
  cout<<ans<<endl;
  }




  return 0;
}
accuracy: 1
time_ms: 1170
memory_kb: 10832
final_rank: 8

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


int N;
double dp[501][501];

double recursive(int num_of_rest_type,int know_num){
	if(dp[num_of_rest_type][know_num] != -1.0)return dp[num_of_rest_type][know_num];

	if(num_of_rest_type == know_num)return 0.0;

	double ret = 0.0;
	int num_cards = 2*num_of_rest_type-know_num;

	if(know_num > 0){
		ret += (double)know_num/(double)num_cards*(recursive(num_of_rest_type-1,know_num-1));
	}

	double new_p = (double)(num_cards-know_num)/(double)(num_cards);
	ret += new_p*(1.0/(double)(num_cards-1))*recursive(num_of_rest_type-1,know_num);
	ret += new_p*(double(know_num)/(double)(num_cards-1))*(1.0+recursive(num_of_rest_type-1,know_num));
	if((num_cards-1-(know_num+1) > 0)){
		ret += new_p*((double)(num_cards-1-(know_num+1))/(num_cards-1))*(1.0+recursive(num_of_rest_type,know_num+2));
	}
	return dp[num_of_rest_type][know_num] = ret;
}

void func(){

	for(int i = 0; i <= N/2; i++){
		for(int k = 0; k <= N/2; k++)dp[i][k] = -1.0;
	}

	printf("%.10lf\n",recursive(N/2,0));
}


int main(){

	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 430
memory_kb: 5120
final_rank: 1

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;

//// < "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\a.txt" > "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\b.txt"

ld memo[1001][1001];
ld getans(const int know, const int notknow) {
	assert(know <= notknow);
	if (memo[know][notknow] < -0.1) {
		if (notknow == 0) {
			memo[know][notknow] = 0.;
		}else{
			ld ans = 0;


			//??\??£????????????
			{
				ld per = ld(know) / notknow;
				if (know) {

					ans += per*(getans(know - 1, notknow - 1));
				}
			}

			if (notknow != know) {
				//??\???????????????
				{
					ld per = ld(notknow - know) / notknow;

					//??£?§£
					{
						ld per2 = 1. / (notknow - 1.);
						ans += per*per2*(getans(know, notknow -2));
					}
					//??\???????????????
					{
						ld per2 = (notknow - know - 2.) / (notknow - 1.);
						if (know + 2 != notknow) {

							ans += per*per2*(1 + getans(know + 2, notknow - 2));
						}
					}
					//??\??£????????????
					{
						ld per2 = ld(know) / (notknow - 1.);
						ans += per*per2*(1 + getans(know, notknow - 2));
					}
				}
			}
			memo[know][notknow] = ans;
		}
	}
	return memo[know][notknow];
}
int main() {
	cout << setprecision(22) << fixed;
	for (int i = 0; i < 1001; ++i) {
		for (int j = 0; j < 1001; ++j) {
			memo[i][j] = -1;
		}
	}
	while (1) {
		int N; cin >> N;
		if (!N)break;
		ld ans = getans(0, N);
		cout << ans << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 18844
final_rank: 9

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
double dp[1020][520];
int n;
double solve(int a,int b){
	if(dp[a][b]>-0.5)return dp[a][b];
	if(a==0)return 0;
	double ret=0;
	if(b>0&&a-b>0)ret+=solve(a-2,b-1)*b/(a-b);
	
	if(a-2*b>0&&a-b>0&&b>0&&a-b-1>0)ret+=(solve(a-2,b)+1)*(a-2*b)/(a-b)*(b)/(a-b-1);
	if(a-2*b>0&&a-b>0&&a-b-1>0&&a-2*b-1>0)ret+=solve(a,b+2)*(a-2*b)/(a-b)*(a-2*b-2)/(a-b-1);
	if(a-2*b>0&&a-b>0&&a-b-1>0)ret+=solve(a-2,b)*(a-2*b)/(a-b)/(a-b-1);
	//printf("%d %d: %f\n",a,b,ret);
	return dp[a][b]=ret+1;
}
int main(){
	int a;
	while(scanf("%d",&a),a){
		a/=2;
		n=a;
		for(int i=0;i<=a*2;i++)for(int j=0;j<=a;j++)
			dp[i][j]=-1;
		printf("%.12f\n",solve(a*2,0)-a);
	}
}
accuracy: 1
time_ms: 930
memory_kb: 5264
final_rank: 5

code_snippet: #include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)

using namespace std;

int N;
double memo[1010][1010];

double dfs(int n,int m){ // n -> already know, m -> unknown
  assert( m >= n );
  if( n >= m ) return 0.0;
  if( memo[n][m] >= 0 ) return memo[n][m];
  double ret = 0;
  // 一枚目が既知のカード

  double know_p = ( (double)n / (double)m );
  if( n )  ret += dfs(n-1,m-1) * know_p;

  // 一枚目がしらないカード
  double unknown_p = 1 - know_p;
  if( m - n >= 1 ) {
    // 二枚目も知らないカード
    if( m - n >= 2 && n+2 <= m-2 ) {
      double unknown = ( m - 1 - n ) ;
      double np = unknown_p * ( (unknown-1) / (double)(m-1) );
      ret += ( 1 + dfs(n+2,m-2) ) * np;
    }
    // 二枚目が偶然知っているカード
    // １枚目と同じ
    if( m - n >= 2 ) { 
      double np = unknown_p * ( 1.0 / (double)(m-1) );
      ret += dfs(n,m-2) * np;
    }

    // １枚目と同じではないが知っているカー土 
    if( n ) {
      double np = unknown_p * ( n / (double)(m-1) );
      ret += ( 1 + dfs(n,m-2) ) *  np ;
    }
  }
  return memo[n][m] = ret;
}

int main(){
  while( cin >> N, N ){
    rep(i,1010)rep(j,1010) memo[i][j] = -1;
    printf("%.8f\n",dfs(0,N));
  }
  return 0;
}
accuracy: 1
time_ms: 1000
memory_kb: 9268
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int MAXN = 1001;
double dp[MAXN][MAXN];

double rec(int r, int m) {
  double &res = dp[r][m];
  if(res != -1.0) return res;
  res = 0.0;
  double p = (double)m/(r*2.0 - m);
  double q = (double)1/(r*2.0 - m - 1.0);
  double s = (double)m/(r*2.0 - m - 1.0);
  if(m) res += p * rec(r-1,m-1);
  if(r-m) res += (1-p) * q * (rec(r-1,m));
  if(m && r-m) res += (1-p) * s * (rec(r-1,m) + 1.0);
  if(r-m >= 2) res += (1-p) * (1-(q+s)) * (rec(r,m+2) + 1.0);
  return res;
}

int main() {
  fill(dp[0], dp[MAXN], -1.0);
  int N;
  while(cin >> N && N) {
    printf("%.10f\n", rec(N/2, 0));
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 9084
final_rank: 3

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

int main()
{
    for(;;){
        int n;
        cin >> n;
        if(n == 0)
            return 0;

        vector<vector<double> > p(n+1, vector<double>(n+2, 0.0));
        p[n][0] = 1.0;
        double ret = 0.0;

        for(int a=n; a>0; a-=2){       // 残りのカード枚数
            for(int b=0; b<=a/2; ++b){ // 位置が分かっているカードの枚数
                // 位置が分かっているカードのもう一方のカードを1枚目で引く
                double p1 = 0.0;
                if(b > 0){
                    p1 = (double)b / (a - b);
                    p[a-2][b-1] += p[a][b] * p1;
                }
                
                // 位置が分かっているカードのもう一方のカードを2枚目で引く
                double p2 = 0.0;
                if(a - b - 1 > 0){
                    p2 = (1.0 - p1) * b / (a - b - 1);
                    p[a-2][b] += p[a][b] * p2;
                    ret += p[a][b] * p2;
                }

                // 1枚目と2枚目が同じ
                double p3 = 0.0;
                if(a - b - 1 > 0){
                    p3 = (1.0 - p1) / (a - b - 1);
                    p[a-2][b] += p[a][b] * p3;
                }

                // ミス
                double p4 = 1.0 - p1 - p2 - p3;
                p[a][b+2] += p[a][b] * p4;
                ret += p[a][b] * p4;
            }
        }

        printf("%.10f\n", ret);
    }
}
accuracy: 1
time_ms: 910
memory_kb: 9012
final_rank: 6

code_snippet: #include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <climits>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;

double memo[1010][1010];
int n;
double solve(int now, int rest) { // rest : 開けたけど残っているもの
  //cout << now << " " << rest << endl;
  if (now >= n) return 0;
  //assert(now != n-1);
  if (memo[now][rest] >= 0) return memo[now][rest];
  int num = rest+1;
  double res = 0;
  double p = (double)rest/(n-now);
  if (rest) {
    res += solve(now+1, rest-1) * p; // 既に開けた奴とマッチ
  }
  // 1枚目が初めて
  p = 1-p;
  if (rest != n-now) {
    // 2枚目が既に開けたやつ
    double q = (double)rest/(n-now-1);
    if (rest) {
      res += (1 + solve(now+2, rest)) * p * q;
    }
    // 2枚目も初めて
    q = double(n-now-1-rest-1)/(n-now-1);
    if (n-now-1-rest-1) {
      res += (1 + solve(now+2, rest+2)) * p * q;
    }
    // 2枚目が同じ
    q = 1.0/(n-now-1);
    res += solve(now+2, rest) * p * q;
  }
  //cout << now << " " << rest << " " << res << endl;
  return memo[now][rest] = res;
}

int main() {
  while(cin>>n,n) {
    REP(i,n)REP(j,n) memo[i][j] = -1;
    
    printf("%.10f\n", solve(0,0));
  }
}
accuracy: 1
time_ms: 1630
memory_kb: 0
final_rank: 4

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <fstream>
#include <cmath>

using namespace std;

#define EPS (1e-10)
#define EQ(a,b) (abs((a)-(b))<EPS)

int m;
double dp[1001][1001];

//ifstream ifs("input.txt");
//#define cin ifs

double dfs(int pos,int mem){
	if(mem<0)return 0;
	else if(pos>=m)return 0;
	else if(m-pos<=mem)return 0;
	else if(dp[pos][mem]>=-0.5)return dp[pos][mem];
	double res=0;
	double per1=1.0*mem/(m-pos);
	// êÚªÌÉ¶Ý
	if(!EQ(per1,0))
		res+=per1*(dfs(pos+1,mem-1));
	if(!EQ(per1,1)){
		double per2=(1.0)/(m-pos-1);
		// êÚÈOÆ}b`
		double per3=((double)mem)/(m-pos-1);
		// êÚÆ}b`
		if(!EQ(per2,0))
			res+=(1-per1)*(per2*(dfs(pos+2,mem)));
		// êÚÈOÌÌàÌÆ}b`
		if(!EQ(per3,0))
			res+=(1-per1)*(per3*(dfs(pos+2,mem)+1));
		// }b`¹¸
		if(!EQ(1-per2-per3,0))
			res+=(1-per1)*(1-per2-per3)*(dfs(pos+2,mem+2)+1);
	}
	return dp[pos][mem]=res;
}

int main(){

	while(cin>>m&&m!=0){
		for(int i=0;i<1001;i++)
			for(int j=0;j<1001;j++)dp[i][j]=-1;
		double res=dfs(0,0);
		printf("%.8f\n",res);
	}

	return 0;
}
accuracy: 1
time_ms: 3180
memory_kb: 0
final_rank: 9

code_snippet: #include <iostream>
#include <set>
#include <cstdio>
#define REP(i,n) for(int i=0; i<(int)(n); i++)

int getInt(){
  int ret = 0,c;
  c = getchar();
  while(!isdigit(c)) c = getchar();
  while(isdigit(c)){
    ret *= 10;
    ret += c - '0';
    c = getchar();
  }
  return ret;
}

using namespace std;

double memo[512][512];

double solve(int rest, int known){
  if(rest == known) return 0.0;
  if(rest <= 1)     return 0.0;
  if(memo[rest][known] > -1)
    return memo[rest][known];

  double ret = 0.0;
  int all     = rest * 2;
  int unknown = all - known;

  {
    // first: unknown one
    double p1 = (double)(unknown - known) / (double)unknown;
    double pp = 1.0;
    {
      // second: the same one
      double p2 = (double)(1) / (double)(unknown - 1);
      ret += p1 * p2 * solve(rest - 1, known);
      pp -= p2;
    }

    if(unknown - 2 - known > 0){
      // second: unknown one
      double p2 = (double)(unknown - 2 - known) / (double)(unknown - 1);
      ret += p1 * p2 * (1.0 + solve(rest, known + 2));
      pp -= p2;
    }

    {
      // second: known one
      double p2 = pp;
      ret += p1 * p2 * (1.0 + solve(rest - 1, known));
    }
  }

  {
    // first: known one
    double p1 = 1.0 - (double)(unknown - known) / (double)unknown;
    ret += p1 * solve(rest - 1, known - 1);
  }

  // printf("solve(%d, %d): %.2f\n", rest, known, ret);

  return memo[rest][known] = ret;
}

int main(){
  while(int n = getInt()){
    int m = n / 2;

    REP(i, m + 1) REP(j, m + 1)
      memo[i][j] = -2.0;

    double ans = solve(m, 0);

    printf("%.8f\n", ans);
  }
  return 0;
}
accuracy: 1
time_ms: 1010
memory_kb: 2932
final_rank: 2