MZOJ #78 小象涂色

分析

一道概率题

对于每一个格子,有c种颜色可以涂,所以

 

初始颜色为1,所以初始化:

 

选定区间,对于每一个格子,有一半的概率选择涂,一半的概率不涂

如果不涂,那么就是原来的颜色,所以这一轮原来的颜色的概率就是

这种颜色原来的概率的一半

如果要涂,那么涂具体一种颜色的概率为1/c

所以,涂色核心程序:

这样做当然要超时

可以小小优化一下(虽然没太大用处):

有没有简单的方法呢,或者我们做了那些无用功?

嗯,好像每个格子都是独立的,

还有,颜色的概率只与涂色的次数有关(没发现的话可以单步调试看看)

那我们可不可以集中处理呢?

直接处理出1~k次涂色的概率,求出每个格子的涂色次数后直接套就好

好主意

每个格子的涂色次数,暴力,或者差分

 

处理相应次数的概率:

 

嗯,好了

 代码

暴力:

 1 /**************************
 2 User:Mandy.H.Y
 3 Language:c++
 4 Problem:elephant
 5 Algorithm:
 6 **************************/
 7 
 8 #include<bits/stdc++.h>
 9 
10 using namespace std;
11 
12 const int maxn = 55;
13 
14 int t,n,c,k;
15 double a[maxn][105]; 
16 double b[105]; 
17 
18 char *TT,*mo,but[(1 << 15) + 2];
19 #define getchar() ((TT == mo && (mo = ((TT = but) + fread(but,1,1 << 15,stdin)), TT == mo)) ? -1 : *TT++)
20 template<class T>inline void read(T &x){
21     x = 0;bool flag = 0;char ch = getchar();
22     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
23     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
24     if(flag) x = -x;
25 }
26 
27 template<class T>void putch(const T x){
28     if(x > 9) putch(x / 10);
29     putchar(x % 10 | 48);
30 }
31 
32 template<class T>void put(const T x){
33     if(x < 0) putchar('-'),putch(-x);
34     else putch(x);
35 }
36 
37 void file(){
38     freopen("elephant.in","r",stdin);
39     freopen("elephant.out","w",stdout);
40 }
41 
42 void readdata(){
43     read(n);read(c);read(k);
44     memset(a,0,sizeof(a));
45     memset(b,0,sizeof(b));
46     for(int i = 1;i <= n; ++ i) a[i][1] = 1;
47 }
48 
49 void work(){
50     readdata();
51     double color = ((double)1.0 / (double)c);
52     for(int z = 1;z <= k; ++ z){
53         int l,r;
54         read(l);read(r);
55         for(int i = l;i <= r; ++ i){
56             for(int j = 0;j < c; ++ j){
57                 a[i][j] *= 0.5;
58                 b[j] = a[i][j] * color;
59             }
60             for(int j = 0;j < c; ++ j){
61                 a[i][j * j % c] += b[j];//这里,本身就只枚举一次 
62                 for(int x = j + 1;x < c; ++ x){//整整少了一半的时间 
63                     a[i][j * x % c] += b[j] + b[x];
64                 }
65             }
66         }
67     }
68     double ans = 0;
69     for(int i = 1;i <= n; ++ i){
70         for(int j = 0;j < c; ++ j){
71             ans += a[i][j] * j;
72         }
73     }
74     printf("%.9lf\n",ans);
75 }
76 
77 int main(){
78     file();
79     read(t);
80     while(t --) 
81         work();
82     return 0;
83 }
View Code

满分:

 1 /**************************
 2 User:Mandy.H.Y
 3 Language:c++
 4 Problem:elephant
 5 Algorithm:
 6 **************************/
 7 
 8 #include<bits/stdc++.h>
 9 
10 using namespace std;
11 
12 const int maxn = 55;
13 
14 int t,n,c,k;
15 int sum[maxn];
16 double cur[maxn][105];
17 double b[105]; 
18 
19 char *TT,*mo,but[(1 << 15) + 2];
20 #define getchar() ((TT == mo && (mo = ((TT = but) + fread(but,1,1 << 15,stdin)), TT == mo)) ? -1 : *TT++)
21 template<class T>inline void read(T &x){
22     x = 0;bool flag = 0;char ch = getchar();
23     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
24     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
25     if(flag) x = -x;
26 }
27 
28 template<class T>void putch(const T x){
29     if(x > 9) putch(x / 10);
30     putchar(x % 10 | 48);
31 }
32 
33 template<class T>void put(const T x){
34     if(x < 0) putchar('-'),putch(-x);
35     else putch(x);
36 }
37 
38 void file(){
39     freopen("elephant.in","r",stdin);
40     freopen("elephant.out","w",stdout);
41 }
42 
43 void readdata(){
44     read(n);read(c);read(k);
45     memset(sum,0,sizeof(sum));
46     memset(cur,0,sizeof(cur));
47     memset(b,0,sizeof(b));
48 }
49 
50 void work(){
51     readdata();
52     double color = ((double)1.0 / (double)c);
53     for(int z = 1;z <= k; ++ z){
54         int l,r;
55         read(l);read(r);
56         sum[l]++;
57         sum[r+1]--;
58     }
59     
60     for(int i = 1;i <= n; ++ i) sum[i] += sum[i-1];
61     cur[0][1] = 1;//初始都是颜色1 
62     for(int i = 1;i <= k; ++ i){
63         for(int j = 0;j < c; ++ j){
64             cur[i][j] = cur[i - 1][j] * 0.5;
65         }
66         for(int j = 0;j < c; ++ j){
67             for(int x = 0;x < c; ++ x){
68                 cur[i][j * x % c] += cur[i-1][j] * 0.5 * color;
69             }
70         }
71     }
72     
73     double ans = 0;
74     for(int i = 1;i <= n; ++ i){
75         for(int j = 0;j < c; ++ j){
76             ans += cur[sum[i]][j] * j;
77         }
78     }
79     printf("%.9lf\n",ans);
80 }
81 
82 int main(){
83 //    file();
84     read(t);
85     while(t --) 
86         work();
87     return 0;
88 }
View Code

 

posted @ 2019-09-03 17:50  Mandy_H_Y  阅读(235)  评论(0编辑  收藏  举报