刷隨機化是真的會上癮quq
洛谷P3973 [TJOI2015]線性代數
- 看oiwiki上說可以隨機化。。。於是。。。
- 就隨機在a[i]上選一位取反,然后更新答案,最后輸出答案。
- 。。。無話可說
- 代碼:
1 #include <bits/stdc++.h> 2 #define nmax 510 3 //D=(A×B−C)×A的轉置 最大 求出一個01矩陣A 4 using namespace std; 5 int b[nmax][nmax]; 6 int c[nmax], a[nmax], t[nmax], anst[nmax]; 7 int n, ans=-1e9; 8 9 void upd(){ 10 int newa = 0; 11 for (int i=1; i<=n; i++) t[i] = 0; 12 for (int i=1; i<=n; i++) for (int j=1; j<=n; j++) t[i] += b[j][i]*a[j]; 13 for (int i=1; i<=n; i++) t[i] -= c[i]; 14 for (int i=1; i<=n; i++) newa += t[i]*a[i]; 15 ans = max(newa, ans); 16 } 17 18 int main(){ 19 srand((unsigned)time(NULL)); 20 cin >> n; 21 for (int i=1; i<=n; i++) { 22 for (int j=1; j<=n; j++) { 23 scanf("%d", &b[i][j]); 24 } 25 } 26 for (int i=1; i<=n; i++) scanf("%d", &c[i]); 27 for (int i=1; i<=n; i++) a[i] = 1; 28 upd(); 29 for (int i=0; i<1000; i++) { 30 int p = rand()%n + 1; 31 a[p] = ( !a[p] ); 32 upd(); 33 } 34 cout << ans << endl; 35 return 0; 36 }
Kangaroo Puzzle
- 2018icpc沈陽的現場賽K題,題目鏈接https://vjudge.net/problem/Gym-101981K
- 隨機輸出U,D,L,R即可,,
- 幾個能用隨機化的關鍵點:保證一定有解(每個袋鼠可以互相到達),只要在50000內出解就行,任意輸出有效解
- 好奇這個答案是怎樣驗證的
- 其實出題人這樣設置就是暗示可以用隨機化吧,,,
- 代碼:
1 #include <cstdio> 2 #include <iostream> 3 #include <cstdlib> 4 #include <ctime> 5 6 using namespace std; 7 char out[4]={'U','L','D','R'}; 8 9 int main(){ 10 srand((unsigned)time(NULL)); 11 int n, m, in; 12 cin >> n >> m; 13 for (int i=0; i<n; i++) for (int j=0; j<m; j++) scanf("%d", &in); 14 for (int i=0; i<50000; i++) printf("%c", out[ rand()%4 ] ); 15 return 0; 16 }
P4581 [BJOI2014]想法
- 刷到省賽的隨機化突然就沒癮了呢。。。
- 這篇題解寫的很好https://www.cnblogs.com/ImagineC/p/10267873.html
- 可以結合這個看看對於n個(0,1)之間的隨機變量x1..xn ,第k小的那個的期望值是 k / (n+1)
- 這題為什么用隨機化:“有95%以上的行的答案和正確答案的誤差不超過25%”,不要求嚴格輸出正解
- 對於每個點隨機(0,RAND_MAX)賦值。到了i點的時候,能得到組成i點的那幾個點中被賦的值中最小的那一個w,那么如果i點是由x個點組成,相當於是隨機在(0,RAND_MAX)取x個點,已知其最小值是w,求x。這樣一個問題。
- 技巧:int M=200000000/n; 盡量擴大嘗試次數,這樣求得的w更接近真實期望
- 代碼:
1 #include <bits/stdc++.h> 2 #define nmax 1000010 3 4 using namespace std; 5 int n,m; //題目數量和想法的數量 6 int a[nmax],b[nmax],c[nmax],mc[nmax]; 7 double w[nmax]; 8 9 int main(){ 10 srand((unsigned)time(NULL)); 11 cin>>n>>m; 12 int M=200000000/n; 13 for (int i=m+1; i<=n; i++) scanf("%d%d",&a[i],&b[i]); 14 for (int j=0; j<M; j++) { 15 for (int i=1; i<=m; i++) { 16 c[i]=rand(); 17 mc[i]=c[i]; 18 } 19 for (int i=m+1; i<=n; i++) { 20 mc[i]=min(mc[ a[i] ] , mc[ b[i] ]); 21 w[i]+=mc[i]/(M*1.0); 22 } 23 } 24 for (int i=m+1; i<=n; i++) printf("%.0lf\n",RAND_MAX/w[i]-1); 25 return 0; 26 }