首頁>技術>

對於給定的一個長度為N的正整數數列 A(1∼N),現要將其分成 M(M≤N)段,並要求每段連續,且每段和的最大值最小。

關於最大值最小:

例如一數列 4 2 4 5 1 要分成 3 段。

將其如下分段:

[4 2][4 5][1]

第一段和為 6,第 2 段和為 9,第 3段和為 1,和最大值為 9。將其如下分段:

[4][2 4][5 1]

第一段和為 4,第 2段和為 6,第 3 段和為 6,和最大值為 6。

並且無論如何分段,最大值不會小於 6。

所以可以得到要將數列 4 2 4 5 1 要分成 3 段,每段和的最大值最小為 6

#include <cstdio>

#include <algorithm>

#include <iostream>

#include <cstring>

#include <cmath>

using namespace std;

int n, m;

long long a[100005] = {0};

long long sum = 0, maxa = 0;

bool check(long long k)

{

long long cnt = 1, temp = 0;

for(int i = 1;i <= n;i++)

{

if(temp + a[i] > k)

{

cnt++;

temp = a[i];

}

else

temp += a[i];

}

return cnt <= m;

}

int main()

{

cin >> n >> m;

for(int i = 1;i <= n;i++)

{

cin >> a[i];

sum += a[i];

maxa = max(maxa, a[i]);

}

long long low = maxa, high = sum;

long long ans;

while(low <= high)

{

long long mid = (low + high) / 2;

if(check(mid))

{

ans = mid;

high = mid - 1;

}

else

low = mid + 1;

}

cout << ans << endl;

return 0;

}

#include <cstdio>

#include <algorithm>

#include <iostream>

#include <cstring>

#include <cmath>

using namespace std;

int n, m;

long long a[100005] = {0};

long long sum = 0, maxa = 0;

bool check(long long k)

{

long long cnt = 1, temp = 0;

for(int i = 1;i <= n;i++)

{

if(temp + a[i] > k)

{

cnt++;

temp = a[i];

}

else

temp += a[i];

}

return cnt <= m;

}

int main()

{

cin >> n >> m;

for(int i = 1;i <= n;i++)

{

cin >> a[i];

sum += a[i];

maxa = max(maxa, a[i]);

}

long long low = maxa, high = sum;

long long ans;

while(low <= high)

{

long long mid = (low + high) / 2;

if(check(mid))

{

ans = mid;

high = mid - 1;

}

else

low = mid + 1;

}

cout << ans << endl;

return 0;

}

10
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 使用深度學習進行影象去噪