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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

poj1505

發布時間:2023/12/9 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 poj1505 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題意:給出一個數列有n個數,要求用分割分把這個數列分成m段,不能改變原數列的順序。每段至少一個數。求使得加和最大的那段的加和最小的劃分方案。如果有多組解的話先要保證第一段和盡量小,若仍有多組解,要先保證第二段和盡量小,以此類推。

分析:二分+貪心。二分查找這個加和最大的段的加和最小值。在查找過程中,每次枚舉這個加和,對數列從左到右看一遍,看在每段加和不超過這個枚舉值的前提下最少可以將這個數列分成幾段。如果分段數小于等于m則這個枚舉值偏大或者剛剛好,如果大于m則說明枚舉值偏小。

找到了這個值之后,我們開始求最優方案,我的做法是先保證最右面那段加和盡量大,其次右數第二段加和盡量大,以此類推。雖然與題中的左面最小的方案不同,但是最終結果是一樣的,因為符合題目要求的那組解一定是左面最小,最終一定會導致右面最大。對于這種右面最大的方式,只需要從右到左將數列走一遍即可。注意處理保證右邊最大之后劃分的段數不足m的情況,要做相應調整以滿足每段至少一個數的要求。即將依次左面沒有分隔符的空位畫上分隔符。

#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <numeric> #include <algorithm> using namespace std;#define MAX_BOOK_NUM 505int book_num, scriber_num; long long book[MAX_BOOK_NUM]; bool cut_before[MAX_BOOK_NUM];void input() {scanf("%d%d", &book_num, &scriber_num);for (int i = 0; i < book_num; i++)scanf("%lld", &book[i]); }bool ok(long long a) {long long temp = 0;int cnt = 1;for (int i = 0; i < book_num; i++){if (temp + book[i] <= a){temp += book[i];continue;}temp = book[i];cnt++;if (cnt > scriber_num)return false;}return cnt <= scriber_num; }long long binary_search() {long long l = *max_element(book, book + book_num);long long r = accumulate(book, book + book_num, 0);while (l < r){long long mid = (l + r) / 2;if (ok(mid))r = mid;elsel = mid + 1;}return l; }void work() {long long each = binary_search();memset(cut_before, 0, sizeof(cut_before));long long temp = 0;int cnt = 0;for (int i = book_num - 1; i >= 0; i--){if (temp + book[i] <= each){temp += book[i];continue;}cut_before[i + 1] = true;temp = book[i];cnt++;}int i = 0;while (cnt < scriber_num - 1){i++;if (!cut_before[i]){cut_before[i] = true;cnt++;}} }void output() {printf("%lld", book[0]);for (int i = 1; i < book_num; i++){if (cut_before[i])printf(" /");printf(" %lld", book[i]);}putchar('\n'); }int main() {int t;scanf("%d", &t);while (t--){input();work();output();}return 0; } View Code

?

轉載于:https://www.cnblogs.com/rainydays/archive/2013/06/12/3132717.html

總結

以上是生活随笔為你收集整理的poj1505的全部內容,希望文章能夠幫你解決所遇到的問題。

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