洛谷P1120小木棒 爆搜+剪枝
生活随笔
收集整理的這篇文章主要介紹了
洛谷P1120小木棒 爆搜+剪枝
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題解
暴搜的思路容易想到,但是剪枝細節有很多,數據很強。
搜索思路:
a. 用dfs(left_num,left_len,bound)表示當前還需要拼left_num根木棒,當前正在拼的木棒還剩left_len長度,搜索是從大往小搜索,并且當前搜索到了bound位置。
b. 每次拼一根木棒都相當于是從大到小搜索一遍所有可用的小木棒。
剪枝的思路:
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小木棒 爆搜+剪枝的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 海底捞学生证打折时间 海底捞学生证打折时
- 下一篇: 人情味是什么意思 人情味的意思