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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【dfs】栅栏的木料(2012特长生 T4)

發布時間:2023/12/3 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【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)的全部內容,希望文章能夠幫你解決所遇到的問題。

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