rp算法 隨機化 刷題記錄


刷隨機化是真的會上癮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 }
    🍔

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM