Day10 T2 邦德

题目

  每个人都知道詹姆斯邦德,著名的007,但很少有人知道很多任务都不是他亲自完成的,而是由他的堂弟们吉米邦德完成(他有很多堂弟),詹姆斯已经厌倦了把一个个任务分配给一个个吉米,他向你求助。
  每个月,詹姆斯都会收到一些任务,根据他以前执行任务的经验,他计算出了每个吉米完成每个任务的成功率,要求每个任务必须分配给不同的人去完成,每个人只能完成一个任务。
  请你编写程序找到一个分配方案使得所有任务都成功完成的概率。
PS:原题:[COCI2006-2007#1] Bond

输入

输入第一行包含一个整数N,表示吉米邦德的数量以及任务的数量(正好相等,1 \(\leqslant\) N \(\leqslant\) 20)。接下来n行每行n个0到100之间的整数,第i行第j个数表示第i个人去执行第j个任务的成功率

输出

输出所有任务成功完成最大的概率,结果保留6位小数。

题解

这一题正解应该是状压DP,然而我不会。
然而搜索+剪枝就可以AC了。
1.如果当前概率乘以余下的吉米邦德完成全部余下任务的最大概率\(\leqslant\)已经搜到的答案,cut。
2.如果当前概率乘以余下的任务被全部完成的最大概率\(\leqslant\)已经搜到的答案,cut。
3.在搜索前按照每个任务被完成的概率从大到小将每个吉米邦德的任务排序,因为在搜索到每个吉米邦德时,选取被完成的概率更大的任务显然更优。

#include<bits/stdc++.h>
using namespace std;
int n;
//tsk[i]表示第i个任务被完成的最大概率,jimmy[i]表示第i个吉米邦德完成一个任务的最大概率
int tsk[25]={0},jimmy[25]={0};;
//jimmymx[i]表示余下n-i+1个吉米邦德完成全部余下任务的最大概率
double jimmymx[25]={0};
bool book[25]={false};
double ans=0.0,taskmx=100.0;

struct node{
    int task,poss;
};
node a[25][25];

bool cmp(node m,node n){
    return m.poss>n.poss;
}

//第step个吉米完成哪个任务,taskrest表示余下的任务被全部完成的最大概率(可能取不到)
void dfs(int step,double possi,double taskrest){
    if(step>n){
        ans=max(ans,possi);
        return;
    }
    if(possi*taskrest/100.0<=ans || possi*jimmy[step]/100.0<=ans) return;//剪枝1&2
    for(register int i=1;i<=n;i++){
        if(!book[a[step][i].task]){
            book[a[step][i].task]=true;
            dfs(step+1,(double)possi*a[step][i].poss/100.0,taskrest/tsk[a[step][i].task]*100.0);
            book[a[step][i].task]=false;
        }
    }
}

int main(){
    scanf("%d",&n);
    for(register int i=1;i<=n;i++){
        for(register int j=1;j<=n;j++){
            scanf("%d",&a[i][j].poss);
            a[i][j].task=j;
            jimmy[i]=max(jimmy[i],a[i][j].poss);
            tsk[j]=max(tsk[j],a[i][j].poss);
        }
    }
    jimmymx[n+1]=100.0;
    for(register int i=n;i>0;i--){
        jimmymx[i]=jimmymx[i+1]*jimmy[i]/100.0;
        taskmx=taskmx*tsk[i]/100.0;
    }
    for(register int i=1;i<=n;i++){
        sort(a[i]+1,a[i]+n+1,cmp);
    }
    dfs(1,100.0,taskmx);
    printf("%.6lf",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/znk161223/p/12219175.html