火山喷发对所有附近的生物具有毁灭性的影响。在本题中,我们希望用数值来模拟这一过程。

在环境里有 n 个生物分别具有 A1​​,A2​​,,An​​点生命值,一次火山喷发总计 MM 轮,每轮造成 11 点伤害,等概率地分给所有存活的生物,即如果目前有 K 个活着的生物,每个生物受到这点伤害的概率是 1/K​​。如果一个生物的生命值减为 0,它会立即死去,此后都不会再占用受到伤害的概率。如果没有生物存活,那么将没有生物会受到伤害。

现在你的任务是,给定 n,M 和全部生物的生命值,问每个生物火山喷发后依然存活的概率。

输入格式

第一行两个正整数 n 和 M。

第二行 nn 个正整数 A_1,...,A_n

输出格式

n 行,第 i 行一个数表示第 i 个生物存活下来的概率,保留小数点后六位。

数据范围与约定

对于 10% 的数据 N=1。

对于 30% 的数据 N=2。

对于全部数据 N4,M120,Ai​​50。

样例输入1

1 2
1

样例输出1

0.000000

样例输入2

3 15
2 12 2

样例输出2

0.001684
0.996632
0.001684

信息传递

计蒜客NOIP2017提高组模拟赛(三)day1

计蒜客NOIP2017提高组模拟赛(三)day1

计蒜客NOIP2017提高组模拟赛(三)day1

样例输入

3 2
0 1 0
0 1 4
1 0 2
4 2 0

样例输出

0.400000
0.350000
0.250000

任性的国王

计蒜客NOIP2017提高组模拟赛(三)day1

计蒜客NOIP2017提高组模拟赛(三)day1

计蒜客NOIP2017提高组模拟赛(三)day1

样例输入

4 14
2 3 4 3 1 1 1 5 4 7
1 1 2
1 2 3
1 1 3
1 2 4
2 1 5
1 1 4
4 2 1
1 1 3
1 2 3
1 2 4
3 3 100
1 3 4
1 2 4
1 1 4

样例输出

6
8
10
13
17
9
5
10
15
16
20

T1:

普通dp(太暴力啦)

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<algorithm>
  4 #include<string>
  5 #define MAXN 5
  6 using namespace std;
  7 namespace solve1{
  8     int a[MAXN];
  9     void solve(int n,int m){
 10         scanf("%d",&a[1]);
 11         double ans;
 12         if(a[1]<=m){
 13             ans=0;
 14             printf("%.6f\n",ans);
 15         }
 16         else{
 17             ans=1;
 18             printf("%.6f\n",ans);
 19         }
 20     }    
 21 }
 22 namespace solve2{
 23     int a[MAXN];
 24     double f[121][51][51];
 25     void solve(int n,int m){
 26         scanf("%d%d",&a[1],&a[2]);
 27         f[0][a[1]][a[2]]=1;
 28         for(int k=1;k<=m;k++){
 29             for(int i=0;i<=a[1];i++){
 30                 for(int j=0;j<=a[2];j++){
 31                     double t;
 32                     if(j){
 33                         t=0.5;
 34                     }
 35                     else{
 36                         t=1;
 37                     }
 38                     if(i<50)f[k][i][j]+=f[k-1][i+1][j]*t;
 39                     if(i){
 40                         t=0.5;
 41                     }
 42                     else{
 43                         t=1;
 44                     }
 45                     if(j<50)f[k][i][j]+=f[k-1][i][j+1]*t;
 46                 }
 47             }
 48         }
 49         double ans1=0,ans2=0;
 50         for(int i=1;i<=a[1];i++){
 51             for(int j=0;j<=a[2];j++){
 52                 ans1+=f[m][i][j];
 53             }
 54         }
 55         for(int i=0;i<=a[1];i++){
 56             for(int j=1;j<=a[2];j++){
 57                 ans2+=f[m][i][j];
 58             }
 59         }
 60         printf("%.6f\n%.6f\n",ans1,ans2);
 61     }
 62 }
 63 namespace solve3{
 64     int a[MAXN];
 65     double f[121][51][51][51];
 66     void solve(int n,int m){
 67         scanf("%d%d%d",&a[1],&a[2],&a[3]);
 68         f[0][a[1]][a[2]][a[3]]=1;
 69         for(int k=1;k<=m;k++){
 70             for(int i=0;i<=a[1];i++){
 71                 for(int j=0;j<=a[2];j++){
 72                     for(int p=0;p<=a[3];p++){
 73                         double t=1;
 74                         double cnt=3;
 75                         if(!j) cnt=cnt-1;
 76                         if(!p) cnt=cnt-1;
 77                         t=t/cnt;
 78                         if(i<50)f[k][i][j][p]+=f[k-1][i+1][j][p]*t;
 79                         t=1;
 80                         cnt=3;
 81                         if(!i) cnt=cnt-1;
 82                         if(!p) cnt=cnt-1;
 83                         t=t/cnt;
 84                         if(j<50)f[k][i][j][p]+=f[k-1][i][j+1][p]*t;
 85                         t=1;
 86                         cnt=3;
 87                         if(!i) cnt=cnt-1;
 88                         if(!j) cnt=cnt-1;
 89                         t=t/cnt;
 90                         if(p<50)f[k][i][j][p]+=f[k-1][i][j][p+1]*t;                        
 91                     }
 92                 }
 93             }
 94         }
 95         double ans1=0,ans2=0,ans3=0;
 96         for(int i=1;i<=a[1];i++){
 97             for(int j=0;j<=a[2];j++){
 98                 for(int p=0;p<=a[3];p++){
 99                     ans1+=f[m][i][j][p];
100                 }
101             }
102         }
103         for(int i=0;i<=a[1];i++){
104             for(int j=1;j<=a[2];j++){
105                 for(int p=0;p<=a[3];p++){
106                     ans2+=f[m][i][j][p];
107                 }
108             }
109         }
110         for(int i=0;i<=a[1];i++){
111             for(int j=0;j<=a[2];j++){
112                 for(int p=1;p<=a[3];p++){
113                     ans3+=f[m][i][j][p];
114                 }
115             }
116         }
117         printf("%.6f\n%.6f\n%.6f\n",ans1,ans2,ans3);
118     }
119 }
120 namespace solve4{
121     int a[MAXN];
122     double f[121][51][51][51];
123     void solve(int n,int m){
124         scanf("%d%d%d%d",&a[1],&a[2],&a[3],&a[4]);
125         f[0][a[1]][a[2]][a[3]]=1;
126         for(int k=1;k<=m;k++){
127             for(int i=0;i<=a[1];i++){
128                 for(int j=0;j<=a[2];j++){
129                     for(int p=0;p<=a[3];p++){
130                         int q=a[4]-(k-(a[1]-i+a[2]-j+a[3]-p));
131                         if(q<0) continue;
132                         double t=1;
133                         double cnt=4;
134                         if(!j) cnt=cnt-1;
135                         if(!p) cnt=cnt-1;
136                         if(!q) cnt=cnt-1;
137                         t=t/cnt;
138                         if(i<50)f[k][i][j][p]+=f[k-1][i+1][j][p]*t;
139                         
140                         t=1;
141                         cnt=4;
142                         if(!i) cnt=cnt-1;
143                         if(!p) cnt=cnt-1;
144                         if(!q) cnt=cnt-1;
145                         t=t/cnt;
146                         if(j<50)f[k][i][j][p]+=f[k-1][i][j+1][p]*t;
147                         
148                         t=1;
149                         cnt=4;
150                         if(!i) cnt=cnt-1;
151                         if(!j) cnt=cnt-1;
152                         if(!q) cnt=cnt-1;
153                         t=t/cnt;
154                         if(p<50)f[k][i][j][p]+=f[k-1][i][j][p+1]*t;    
155                         
156                         t=1;
157                         cnt=4;        
158                         if(!i) cnt=cnt-1;
159                         if(!j) cnt=cnt-1;
160                         if(!p) cnt=cnt-1;
161                         t=t/cnt;
162                         f[k][i][j][p]+=f[k-1][i][j][p]*t;        
163                     }
164                 }
165             }
166         }
167         double ans1=0,ans2=0,ans3=0,ans4=0;
168         for(int i=1;i<=a[1];i++){
169             for(int j=0;j<=a[2];j++){
170                 for(int p=0;p<=a[3];p++){
171                     ans1+=f[m][i][j][p];
172                 }
173             }
174         }
175         for(int i=0;i<=a[1];i++){
176             for(int j=1;j<=a[2];j++){
177                 for(int p=0;p<=a[3];p++){
178                     ans2+=f[m][i][j][p];
179                 }
180             }
181         }
182         for(int i=0;i<=a[1];i++){
183             for(int j=0;j<=a[2];j++){
184                 for(int p=1;p<=a[3];p++){
185                     ans3+=f[m][i][j][p];
186                 }
187             }
188         }
189         
190         for(int i=0;i<=a[1];i++){
191             for(int j=0;j<=a[2];j++){
192                 for(int p=0;p<=a[3];p++){
193                     int q=a[4]-(m-(a[1]-i+a[2]-j+a[3]-p));
194                     if(q){
195                         ans4+=f[m][i][j][p];
196                     }
197                 }
198             }
199         }
200         printf("%.6f\n%.6f\n%.6f\n%.6f\n",ans1,ans2,ans3,ans4);
201     }
202 }
203 int main()
204 {
205     int n,m;
206     scanf("%d%d",&n,&m);
207     if(1==n){
208         solve1::solve(n,m);
209     }
210     else if(2==n){
211         solve2::solve(n,m);
212     }
213     else if(3==n){
214         solve3::solve(n,m);
215     }
216     else{
217         solve4::solve(n,m);
218     }
219     return 0;
220 }
Code1-1

其实这题可用bfs转移状态,因为按照总伤害,前面的不会对后面的产生影响,所以开始轮到队头元素时,一定是最优的

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<queue>
  6 #define MAXN 52
  7 using namespace std;
  8 struct Node{
  9     int a[4];
 10     Node(int p1=0,int p2=0,int p3=0,int p4=0){
 11         a[0]=p1,a[1]=p2,a[2]=p3,a[3]=p4;
 12     }
 13 };
 14 queue<Node> q;
 15 double f[52][52][52][52];
 16 bool b[52][52][52][52];
 17 int n,m;
 18 
 19 int main()
 20 {
 21     int a[4]={0},c[4]={0};
 22     scanf("%d%d",&n,&m);
 23     for(int i=0;i<n;i++){
 24         scanf("%d",&c[i]);
 25     }
 26     f[c[0]][c[1]][c[2]][c[3]]=1;
 27     q.push(Node(c[0],c[1],c[2],c[3]));
 28     while(!q.empty()){
 29         memcpy(a,q.front().a,sizeof(a));
 30         int sum=0;
 31         for(int i=0;i<4;i++){
 32             sum+=(c[i]-a[i]);
 33         }
 34         if(sum>m){
 35             break;
 36         }
 37         q.pop();
 38         int cnt=0;
 39         for(int i=0;i<4;i++){
 40             if(a[i]){
 41                 cnt++;
 42             }
 43         }
 44         double t=1/(double)cnt;
 45         if(a[0]){
 46             f[a[0]-1][a[1]][a[2]][a[3]]+=f[a[0]][a[1]][a[2]][a[3]]*t;
 47             if(!b[a[0]-1][a[1]][a[2]][a[3]]){
 48                 b[a[0]-1][a[1]][a[2]][a[3]]=1;
 49                 q.push(Node(a[0]-1,a[1],a[2],a[3]));
 50             }
 51         }
 52         if(a[1]){
 53             f[a[0]][a[1]-1][a[2]][a[3]]+=f[a[0]][a[1]][a[2]][a[3]]*t;
 54             if(!b[a[0]][a[1]-1][a[2]][a[3]]){
 55                 b[a[0]][a[1]-1][a[2]][a[3]]=1;
 56                 q.push(Node(a[0],a[1]-1,a[2],a[3]));
 57             }
 58         }
 59         if(a[2]){
 60             f[a[0]][a[1]][a[2]-1][a[3]]+=f[a[0]][a[1]][a[2]][a[3]]*t;
 61             if(!b[a[0]][a[1]][a[2]-1][a[3]]){
 62                 b[a[0]][a[1]][a[2]-1][a[3]]=1;
 63                 q.push(Node(a[0],a[1],a[2]-1,a[3]));
 64             }
 65         }
 66         if(a[3]){
 67             f[a[0]][a[1]][a[2]][a[3]-1]+=f[a[0]][a[1]][a[2]][a[3]]*t;
 68             if(!b[a[0]][a[1]][a[2]][a[3]-1]){
 69                 b[a[0]][a[1]][a[2]][a[3]-1]=1;
 70                 q.push(Node(a[0],a[1],a[2],a[3]-1));
 71             }
 72         }
 73     }
 74     double ans[4];
 75     if(n>=1){
 76         ans[0]=0;
 77         for(int i=1;i<=c[0];i++){
 78             for(int j=0;j<=c[1];j++){
 79                 for(int k=0;k<=c[2];k++){
 80                     for(int l=0;l<=c[3];l++){
 81                         if(c[0]-i+c[1]-j+c[2]-k+c[3]-l==m)
 82                             ans[0]+=f[i][j][k][l];
 83                     }
 84                 }
 85             }
 86         }        
 87     }
 88     if(n>=2){
 89         ans[1]=0;
 90         for(int i=0;i<=c[0];i++){
 91             for(int j=1;j<=c[1];j++){
 92                 for(int k=0;k<=c[2];k++){
 93                     for(int l=0;l<=c[3];l++){
 94                         if(c[0]-i+c[1]-j+c[2]-k+c[3]-l==m)
 95                             ans[1]+=f[i][j][k][l];
 96                     }
 97                 }
 98             }
 99         }        
100     }
101     if(n>=3){
102         ans[2]=0;
103         for(int i=0;i<=c[0];i++){
104             for(int j=0;j<=c[1];j++){
105                 for(int k=1;k<=c[2];k++){
106                     for(int l=0;l<=c[3];l++){
107                         if(c[0]-i+c[1]-j+c[2]-k+c[3]-l==m)
108                             ans[2]+=f[i][j][k][l];
109                     }
110                 }
111             }
112         }        
113     }
114     if(n>=4){
115         ans[3]=0;
116         for(int i=0;i<=c[0];i++){
117             for(int j=0;j<=c[1];j++){
118                 for(int k=0;k<=c[2];k++){
119                     for(int l=1;l<=c[3];l++){
120                         if(c[0]-i+c[1]-j+c[2]-k+c[3]-l==m)
121                             ans[3]+=f[i][j][k][l];
122                     }
123                 }
124             }
125         }        
126     }
127     for(int i=0;i<n;i++){
128         printf("%.6f\n",ans[i]);
129     }
130     return 0;
131 }
Code1-2

T2:

矩阵快速幂

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #define MAXN 205
 6 using namespace std;
 7 int n,T;
 8 int d[MAXN][MAXN];
 9 int sum[MAXN];
10 struct Mat{
11     double a[MAXN][MAXN];
12     Mat operator *= (const Mat &B){
13         Mat C;
14         for(int i=1;i<=n;i++){
15             for(int j=1;j<=n;j++){
16                 C.a[i][j]=0;
17                 for(int k=1;k<=n;k++){
18                     C.a[i][j]+=a[i][k]*B.a[k][j];
19                 }
20             }
21         }
22         memcpy(a,C.a,sizeof(a));
23         return *this;
24     }
25 };
26 void Floyed(){
27     for(int k=1;k<=n;k++){
28         for(int i=1;i<=n;i++){
29             for(int j=1;j<=n;j++){
30                 d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
31             }
32         }
33     }
34     for(int i=1;i<=n;i++){
35         sum[i]=0;
36         for(int j=1;j<=n;j++){
37             sum[i]+=d[i][j];
38         }
39     }
40 }
41 int main()
42 {
43     double a[MAXN];
44     scanf("%d%d",&n,&T);
45     for(int i=1;i<=n;i++){
46         scanf("%lf",&a[i]);
47     }
48     for(int i=1;i<=n;i++){
49         for(int j=1;j<=n;j++){
50             scanf("%d",&d[i][j]);
51         }
52     }
53     Floyed();
54     Mat A;
55     for(int i=1;i<=n;i++){
56         for(int j=1;j<=n;j++){
57             A.a[i][j]=(double)d[i][j]/(double)sum[j];
58         }
59     }
60     Mat B;
61     memcpy(B.a,A.a,sizeof(B.a));
62     T--;
63     while(T){
64         if(T&1){
65             B*=A;
66         }
67         A*=A;
68         T>>=1;
69     }
70     for(int i=1;i<=n;i++){
71         double ans=0;
72         for(int j=1;j<=n;j++){
73             ans+=a[j]*B.a[i][j];
74         }
75         printf("%.6f\n",ans);
76     }
77     return 0;
78 }
Code2

相关文章:

  • 2021-10-12
  • 2021-04-26
  • 2022-12-23
  • 2022-02-13
  • 2021-09-16
  • 2022-01-02
  • 2022-01-12
  • 2021-06-07
猜你喜欢
  • 2021-05-17
  • 2021-12-10
  • 2022-01-23
  • 2021-12-05
  • 2021-05-20
  • 2022-03-03
  • 2021-12-30
相关资源
相似解决方案