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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hdu4876 深搜+(随机枚举剪枝)

發(fā)布時(shí)間:2025/6/17 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu4876 深搜+(随机枚举剪枝) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題意:
? ? ? 給你n個(gè)數(shù),讓你從選擇k個(gè)數(shù),然后排成一個(gè)環(huán)(k個(gè)數(shù)的順序隨意,但是排成一個(gè)環(huán)后就不能變了),然后可以在這個(gè)環(huán)上任意的找連續(xù)w個(gè)數(shù)(w<=k),可以找多次,得到一個(gè)值等于當(dāng)前找的連續(xù)的數(shù)的異或和,最后問你能找到>=L&&<=R的最大的R,L,R之間的數(shù)必須全部存在,給你N,K,L,求最大的R.

思路:

? ? ? 直接先暴力找到k個(gè)數(shù)(最多C(20,6)),然后在枚舉這k個(gè)數(shù)的全排列(全排列有STL函數(shù),不想用可以自己深搜枚舉),對(duì)于每一個(gè)序列求出所有可能解,找到最大的R,更新答案,這里有一個(gè)很重要的剪枝,也是這個(gè)題目的核心就是在全排列之前可以先判斷一下是否可能存在可以更新R的最優(yōu)解,直接深搜枚舉當(dāng)前這k個(gè)數(shù)(不用管順序,是找可能存在),看看組成的最大的是否比當(dāng)前的最大R大,如果不是,那么就沒必要全排列再去枚舉了,時(shí)間復(fù)雜度 深搜判斷是 O(2^5) 而直接來全排列+枚舉是 O(5! * 5 * 5),題目說的是隨機(jī)數(shù)據(jù),所以不存在那種全是極端數(shù)據(jù),也就是所有情況都滿足的數(shù)據(jù),所以相比之下,還是加上那個(gè)剪枝比較合算。


#include<stdio.h> #include<string.h> #include<algorithm> using namespace std;int N ,K ,L ,R ,ks; int num[25] ,mark[130]; int now[25];void mk_jude(int k ,int sum) {if(k == K + 1) return ;mark[sum ^ now[k]] = 1;mk_jude(k + 1 ,sum ^ now[k]);mk_jude(k + 1 ,sum); }int jude(int k ,int sum) {memset(mark ,0 ,sizeof(mark));mk_jude(1 ,0);for(int i = L ;i <= R ;i ++)if(!mark[i]) return 0;return 1; }void dfs(int k ,int I) {if(k == K + 1){ if(!jude(1 ,0)) return;int tmp[25];for(int i = 1 ;i <= K ;i ++)tmp[i] = now[i];for(int tt = 1 ;tt <= ks ;tt ++){memset(mark ,0 ,sizeof(mark));for(int i = 1 ;i <= K ;i ++){int sum = 0;for(int j = 1 ;j <= K ;j ++){int a = i + j - 1;if(a > K) a -= K;sum = sum ^ tmp[a];mark[sum] = 1;}} int mk = 0;for(int i = L ;1 ;i ++)if(!mark[i]){mk = i - 1;break; } if(R < mk) R = mk;next_permutation(tmp + 1 ,tmp + K + 1);}return ;}if(I == N + 1) return;now[k] = num[I];dfs(k + 1 ,I + 1);dfs(k ,I + 1); }int main () {int i;while(~scanf("%d %d %d" ,&N ,&K ,&L)){for(i = 1 ;i <= N ;i ++)scanf("%d" ,&num[i]);for(R = 0 ,ks = 1 ,i = 2 ;i <= K ;i ++)ks *= i;dfs(1 ,1);if(R < L) R = 0;printf("%d\n" ,R);}return 0; }

總結(jié)

以上是生活随笔為你收集整理的hdu4876 深搜+(随机枚举剪枝)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。