题意:有 n n n种不同的卡牌,每一次抽卡获得第 i i i种卡牌的概率为 p i pi pi。如果这张卡牌已经获得,就会转化为一枚硬币。可以用 k k k枚硬币交换一张没有获得过的卡。求获得所有种类的牌的概率。
#include<bits/stdc++.h>
using namespace std;
double dp[100][65636];//抽取层数,状态的概率
double p[30];
int book[65636];
int n,k;
double dfs(int level,int state,int need)
{
if((n-need)*k<=level-need)//层数大于剩余数*k就退出
return level;
double ans=0;
for(int i=0;i<n;i++)
{
if(book[i]==0)//没有选过这种卡牌
{
book[i]=1;
if(dp[level+1][state+(1<<i)]==0)
dp[level+1][state+(1<<i)]=dfs(level+1,state+(1<<i),need+1);
ans+=p[i]*dp[level+1][state+(1<<i)];
book[i]=0;//树枝搜索结束后需要将标记清理,因为这是限制搜索应当一直向下
}
else//重复选牌
{
if(dp[level+1][state]==0)
dp[level+1][state]=dfs(level+1,state,need);
ans+=p[i]*dp[level+1][state];
}
}
return ans;
}
int main()
{
cin>>n>>k;
for(int i=0;i<n;i++)cin>>p[i];
double ans=dfs(0,0,0);
printf("%.10lf\n",ans);
return 0;
}