日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

牛客 - Dress as women(sg定理+位运算)

發布時間:2024/4/11 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客 - Dress as women(sg定理+位运算) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:兩個人正在玩游戲,現在給出 n 個點,兩個人輪流操作,每次可以選擇任意個貢獻的頂點然后刪除,最后無法操作的人失敗

題目分析:讀完題后想到了之前做過的一道題目:點擊查看

因為 n 比較小,不難想到狀態壓縮,所以最樸素的做法就是設 m = 2^n ,直接 m * m 枚舉狀態然后寫 dfs 轉移狀態就好了,在此之前需要記得預處理一下共線的限制,共線限制也可以利用狀態壓縮來保存,只需要判斷每個二進制狀態中所有為 1 的位置是否共線即可,在處理共線限制時,因為時間復雜度計算的比較充裕,所以我直接選擇了 2^n * n^3 來預處理(正解好像是 2^n *n 的時間復雜度預處理的),原理就是:如果某些頂點貢獻,那么任意三個頂點都共線,這樣 2^n 枚舉狀態,n^3 枚舉三個頂點判斷是否貢獻即可,這樣總的時間復雜度就是 4^n ,還好出題人沒有卡時間,1.2s 水過去了

但顯然這樣肯定不是正解,賽后補題時,仔細分析了一下,發現:

假設當前是狀態 x 向狀態 y 進行轉移,那么對于任意一個位置來說,只會有三種情況:

  • x = 0 , y = 0,當前位置之前就被刪除
  • x = 0 , y = 1,本輪操作刪除當前位置
  • x = 1 , y = 1,當前位置本輪也不刪除
  • 注意到沒有,當 x = 1 且 y = 0 時的這個狀態是不合法的,所以我們完全可以通過搜索進行剪枝將時間復雜度降低到 3^n,這也正需要一個小知識點:如何枚舉子集的子集

    當然只需要兩行代碼就可以實現

    for (int S=1; S<(1<<n); S++)for (int S0=S;S0;S0=(S0-1)&S)

    然后實現就非常簡單了

    代碼:
    ?

    #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=15;int n;LL x[N],y[N];bool can[(1<<N)+100];int dp[(1<<N)+100];void init() {auto check=[&](int i,int j,int k){return (y[i]-y[j])*(x[i]-x[k])==(y[i]-y[k])*(x[i]-x[j]);};for(int t=1;t<1<<n;t++){can[t]=true;for(int i=0;i<n;i++){if((t&(1<<i))==0)continue;for(int j=i+1;j<n;j++){if((t&(1<<j))==0)continue;for(int k=j+1;k<n;k++){if((t&(1<<k))==0)continue;if(!check(i,j,k))can[t]=false;}} } } }int main() { #ifndef ONLINE_JUDGE // freopen("input.txt","r",stdin); // freopen("output.txt","w",stdout); #endif // ios::sync_with_stdio(false);scanf("%d",&n);for(int i=0;i<n;i++)scanf("%lld%lld",x+i,y+i);init();for(int i=0;i<1<<n;i++)for(int j=i;j;j=(j-1)&i)if(can[j]&&!dp[i^j])dp[i]=true;if(dp[(1<<n)-1])puts("zyh");elseputs("fzj");return 0; }

    ?

    總結

    以上是生活随笔為你收集整理的牛客 - Dress as women(sg定理+位运算)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。