在挑战程序设计竞赛上做过类似的,二分答案判断是否合理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| #include <cstdio> #include <stack> using namespace std; typedef long long LL;
const int maxn = 510; LL a[maxn]; stack <LL> p[maxn]; int m,k;
bool ok(LL ans) { int pos=m,t=k; while(t--){ LL cur=ans; while(cur>a[pos]){ cur-=a[pos--]; if(!pos) return true; } } return !pos; }
int main() { int t; scanf("%d", &t); while(t--) { scanf("%d%d", &m, &k); LL l = 0, r = 6000000000; for(int i = 1; i <= m; ++i) scanf("%lld", &a[i]), l = max(l, a[i]); LL mid = (l + r) / 2; while(l < r) { mid = l + (r - l) / 2; if(ok(mid)){ if(!ok(mid - 1)){--mid; break;} else r = mid + 1; } else l = mid; } if(ok(l)) mid = l; int pos = m; for(int i = k; i > 0; --i){ while(!p[i].empty()) p[i].pop(); LL t = mid; while(t >= a[pos] && pos) { t-=a[pos], p[i].push(a[pos--]); if(pos < i) break; } } for(int i = 1; i <= k; ++i) { while(!p[i].empty()){ printf("%lld", p[i].top()), p[i].pop(); if(!p[i].empty()) printf(" "); } printf(i == k ? "\n" : " / "); } } return 0; }
|
** 本文迁移自我的CSDN博客,格式可能有所偏差。 **