The secret code
The secret code
Input file: stdinOutput file: stTime limit: 1 sec
Memory limit: 256 Mb
After returning from the trip, Alex was unpleasantly surprised: his porch door had a new combination lock. Alex
can not get into his house! Code lock contains N disks, each of which can be in one of M positions. There
is only one correct position. Alex thoroughly inspected discs and by fingerprints and scratches determined the
probability of each position for each disk. Now Alex has K attempts to guess the correct code: if he fails, his
vigilant neighbors will call the police, and Alex will have a hard time persuading cops that he is not a thief, but
tried to get home. Help Alex to calculate the maximum probability of getting home, not to the police.
Limit
1 ≤ N ≤ 100
1 ≤ M ≤ 20
1 ≤ K ≤ 100
0 ≤ P ij ≤ 100
Input
The first line of input file contains three integers: N, M Рё K.
Next N lines contain M integers each: j-th number of the i-th line (P ij ) — the probability of a situation where
i-th disc’s correct position is j. Given that
P M
j=1 P ij
= 100.
Output
Print a single number — Alex’s chances to guess the correct code in time. Output result should have an absolute
percentage error not grater than 10 −7 .
Example
stdin
2 2 1
50 50
10 90
3 5 4
10 15 20 25 30
1 2 3 4 90
100 0 0 0 0
stdout
0.45
0.81
题目大意:
n个数列,每个数列取一个数,得到这些数的乘积,求前k个最大的乘积。
多谢syx的指导!
解题思路:
对每个数列排序后。
首先,第一大的自然是所有数列最大值乘积。
接着,将最大乘积加到ans上,然后将这个乘积能够达到的所有下一个状态均加入优先队列中。至于保存状态,每个状态只需保存其在每个数列的取到第几个数的指针即可,显然下一个状态是在该状态之后,并且出现在某一个指针向后移位。故将所有下一个状态加入优先队列。
然后,当找到第k个或者是空队列时退出循环,否则返回上一步。
最后,输出答案。
实现方法,直接使用STL中的priority_queue,若数据量加大,可惜优先队列不能删除尾节点,不过可利用最大最小堆保存前k个即可。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <utility> #include <stack> #include <queue> #include <map> #include <deque> #define max(x,y) ((x)>(y)?(x):(y)) #define min(x,y) ((x)<(y)?(x):(y)) using namespace std; struct State{ int head[105]; double x; bool operator<(const State &b) const { return x<b.x; } }; double a[105][21]; int n,m,k; priority_queue<State> q; bool cmp(double x, double y) { return x>y; } int main() { scanf("%d%d%d",&n,&m,&k); for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { scanf("%lf",&a[i][j]); a[i][j]/=100; } sort(a[i],a[i]+m,cmp); } State tmp; tmp.x=1.0; for(int i=0; i<n; i++) { tmp.head[i]=0; tmp.x*=a[i][0]; } q.push(tmp); double ans=0.0; for(int i=0; i<k&&!q.empty(); i++) { tmp=q.top(); q.pop(); ans+=tmp.x; for(int j=0; j<n; j++) if(tmp.head[j]<m-1) { if(a[j][tmp.head[j]+1]==0) continue; tmp.x=tmp.x / a[j][tmp.head[j]] * a[j][tmp.head[j]+1]; tmp.head[j]++; q.push(tmp); tmp.x=tmp.x / a[j][tmp.head[j]] * a[j][tmp.head[j]-1]; tmp.head[j]--; } } printf("%.8f\n",ans); return 0; }