3602: 中獎啦!(史上最強水解!!!沒有之一!!!)
3602: 中獎啦!時間限制(普通/Java):1000MS/3000MS 記憶體限制:65536KByte描述 L超時由於最近銷售量特別好。為答謝廣大的顧客,L公司準備舉行抽獎活動。而規則如下:超市會發行一批刮獎卡,每張刮獎卡刮開上面的圖層會,會出現幾種圖案中的一種(每種圖案出現的機率是一樣的),只要集齊n種圖案就算中獎。現在某人買了m張卡片,你能算出他中獎的概率P是多少麼? 輸入
有多組測試資料。 輸入以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;
}