【dfs】栅栏的木料(2012特长生 T4)
生活随笔
收集整理的這篇文章主要介紹了
【dfs】栅栏的木料(2012特长生 T4)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目大意
給你n個木板,給你這些木板的長度,你可以把這些木板切開,現在有m個木料,問你最多可以切出多少個木料
解題思路
可以dfs枚舉每個木料用哪個木板來切
但這樣顯然會超時,那么考慮剪枝
1.對于一些木板,連最小的木料都切不出來,那么顯然不要
2.對于一些木料,臉最大的木板都無法切出它,那么也不要
3.切木板顯然盡量切小的,因為可以切出大的那么肯定可以切出小的,對此可以二分答案,當一塊木板剩余大小連最小的都切不了了,那么剩下的就浪費了,當浪費的大于木板總量減去二分的木料總量(剩下的不可能切出來),那么久退出
4.先用大的木塊,先切大的木料
5.當有相同的木料時,所選木塊編號不小于前一個
6.當最大木塊可以切出若干最小木料時,二分左指針往右
代碼
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define N 1021 using namespace std; int n, m, l, r, mw, mn, wst, mid, summ, a[50], b[N], sum[N]; bool dfs(int x, int lst) {if (!x) return true;for (int i = b[x] == b[x + 1] ? lst : mn; i <= n; ++i)//相同的編號比上一個大{if (a[i] < b[x] || a[i] == a[i - 1]) continue;//木塊相同就不再dfs了a[i] -= b[x];if (a[i] < b[1]){wst += a[i];//浪費的if (wst > mw){wst -= a[i];a[i] += b[x];continue;}}if (dfs(x - 1, i)){a[i] += b[x];return true;}if (a[i] < b[1])wst -= a[i];a[i] += b[x];}return false; } int main() {scanf("%d", &n);for (int i = 1; i <= n; ++i)scanf("%d", &a[i]);scanf("%d", &m);for (int i = 1; i <= m; ++i)scanf("%d", &b[i]);sort(a + 1, a + 1 + n);sort(b + 1, b + 1 + m);mn = 1;for (int i = 1; i <= n; ++i)if (a[i] < b[1]) mn++;//最小的都切不出來else summ += a[i];for (int i = 1; i <= m; ++i){sum[i] = sum[i - 1] + b[i];if (b[i] > a[n] || sum[i] > summ){m = i - 1;//大于總值了break;}}l = 1;r = m;while(a[n] >= sum[l + 1]) l++;//最大的可以解決這些全部reverse(a + mn, a + n + 1);while(l < r){mid = (l + r + 1) >> 1;wst = 0;mw = summ - sum[mid];if (dfs(mid, mn)) l = mid;//二分else r = mid - 1;}printf("%d", l);return 0; }總結
以上是生活随笔為你收集整理的【dfs】栅栏的木料(2012特长生 T4)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 打印机与复印机有什么区别复印机和打印机有
- 下一篇: 【bfs】廉价最短路径(2013特长生