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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

洛谷P1120小木棒 爆搜+剪枝

發布時間:2023/12/3 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 洛谷P1120小木棒 爆搜+剪枝 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題解

暴搜的思路容易想到,但是剪枝細節有很多,數據很強。
搜索思路:
a. 用dfs(left_num,left_len,bound)表示當前還需要拼left_num根木棒,當前正在拼的木棒還剩left_len長度,搜索是從大往小搜索,并且當前搜索到了bound位置。
b. 每次拼一根木棒都相當于是從大到小搜索一遍所有可用的小木棒。
剪枝的思路:

  • 拼小木棒的時候從大到小枚舉。
  • 當前枚舉的小木棒a[i]如果是拼成一根大木棒的最后一根小木棒,但是最后卻沒有拼成所有的大木棒,那么直接從此返回失敗。因為如果之后的小木棒組合能拼成所有的大木棒,那么可以將a[i]與其中的一些做置換,得到等效局面。
  • 假設某根大木棒剛要開始枚舉,剩余要找長度為目標大木棒長度,但是沒有拼成所有的大木棒,那么直接返回失敗。因為這表明無法再繼續拼成任何一根大木棒了。
    4.如果當前拼接長度為a[i]的木棒發生失敗,那么任何長度等于a[i]的木棒都可以直接跳過。
  • ##代碼

    #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; const int maxn = 100; int a[maxn],vis[maxn]; int n,tot,len; bool dfs(int left_num,int left_len,int bound){//表示剩余要拼left_num根木棒,當前再拼的剩余left_len,下一個從bound開始if(left_num == 0 && left_len == 0) return true;if(left_len == 0){return dfs(left_num-1,len,tot-1);}for(int i = bound;i >= 0;--i){if(vis[i]) continue;if(a[0] > left_len) return false;vis[i] = 1;if(dfs(left_num,left_len-a[i],i-1)) return true;vis[i] = 0;if(left_len - a[i] == 0 || left_len == len) return false;while(i && a[i-1] == a[i]) --i;}return false; } int main(){scanf("%d",&n);int mi = 0,sum = 0;for(int i = 0;i < n;++i) {int tmp;scanf("%d",&tmp);if(tmp > 50) continue;a[tot++] = tmp;sum += tmp;mi = max(mi,tmp);}sort(a,a+tot);for(len = mi;len <= sum / 2;++len){if(sum % len != 0) continue;memset(vis,0,sizeof(vis));if(dfs(sum/len,0,0))return 0*printf("%d\n",len);}printf("%d\n",sum);return 0; }

    總結

    以上是生活随笔為你收集整理的洛谷P1120小木棒 爆搜+剪枝的全部內容,希望文章能夠幫你解決所遇到的問題。

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