1. 程式人生 > >3602: 中獎啦!(史上最強水解!!!沒有之一!!!)

3602: 中獎啦!(史上最強水解!!!沒有之一!!!)

3602: 中獎啦! 

時間限制(普通/Java):1000MS/3000MS     記憶體限制:65536KByte

描述

L超時由於最近銷售量特別好。為答謝廣大的顧客,L公司準備舉行抽獎活動。而規則如下:超市會發行一批刮獎卡,每張刮獎卡刮開上面的圖層會,會出現幾種圖案中的一種(每種圖案出現的機率是一樣的),只要集齊n種圖案就算中獎。現在某人買了m張卡片,你能算出他中獎的概率P是多少麼?

輸入

有多組測試資料。
每組資料只有一行,包含2個數字n,m(1<=n,m<=10),分別代表圖案的種類與某人購買的卡片的數量。

輸入以0 0結束。

輸出

每組資料輸出佔一行,是1個實數P,即中獎概率(P保留4位小數)。

樣例輸入

樣例輸出


emmmm、、、這是一道概率論的題目。基本模型是有放回摸球模型,具體的百度模型應該很多

、、、說了這麼多,我也不會做啊!不過有些題總有水的做法!

下面附上dfs打表程式碼(emmmm、、、差不多執行半小時能出全部結果吧、、、或許加記憶化搜尋能更快點、):

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<string>
#include<set>
#include<cmath>
#define ll long long
#define INF 0x3f3f3f3f
#define N 1005
using namespace std;


ll n,m,sum,mm;
ll a[11];
set<int> s;
set<int>::iterator it;
void dfs(int cnt)
{
//cout<<s.size()<<' '<<endl;
//for(it=s.begin();it!=s.end();it++)
//cout<<*it<<' ';cout<<endl;
if(s.size()==n)
{
//cout<<"pow"<<pow(n,m-cnt)<<endl;
sum+=pow(n,m-cnt);
return;
}
if(cnt==m&&s.size()<n){
return;
}
for(int i=1;i<=n;i++)
{
s.insert(i);
a[i]++;
dfs(cnt+1);
a[i]--;
if(!a[i])
{
it=s.find(i);
s.erase(it);
}
}
}


int main()
{
for(int i=1;i<=10;i++){
for(int j=1;j<=10;j++){
sum=0;
s.clear();
n=i;m=j;
memset(a,0,sizeof(a));
mm=pow(n,m);
dfs(0);
double x=1.0*sum/mm;
if(x>1) x=1;
printf("%.4lf,",x);
}cout<<endl;
}cout<<"end"<<endl;
return 0;
}

這就是上面程式打出來的表AC的啦!(話說一覺睡醒表打完還真過了!哈哈哈。。。)

note:其實時間主要花在10 10打最後一個數上,由規律可得輸入10 10的概率大於0小於0.0009,那麼多交幾次就AC啦!

#include<cstdio>
double a[10][10]={1.0000,1.0000,1.0000,1.0000,1.0000,1.0000,1.0000,1.0000,1.0000,1.0000,
0.0000,0.5000,0.7500,0.8750,0.9375,0.9688,0.9844,0.9922,0.9961,0.9980,
0.0000,0.0000,0.2222,0.4444,0.6173,0.7407,0.8258,0.8834,0.9221,0.9480,
0.0000,0.0000,0.0000,0.0938,0.2344,0.3809,0.5127,0.6229,0.7114,0.7806,
0.0000,0.0000,0.0000,0.0000,0.0384,0.1152,0.2150,0.3226,0.4271,0.5225,
0.0000,0.0000,0.0000,0.0000,0.0000,0.0154,0.0540,0.1140,0.1890,0.2718,
0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0061,0.0245,0.0577,0.1049,
0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0024,0.0108,0.0282,
0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0009,0.0047,
0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0004
};
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m),n||m)
{
printf("%.4lf\n",a[n-1][m-1]);
}
return 0;
}