uva 1443 dp+二分

来源:互联网 发布:gps nema数据 编辑:程序博客网 时间:2024/06/15 19:36
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 4E5 + 10;const int INF = 0x3f3f3f3f;int init[maxn], sum[maxn], dp[maxn][2], n, m, d, T;bool check(int x){memset(dp, INF, sizeof(dp));dp[0][0] = 0;for (int i = 2; i <= n; i += 2)for (int len = 1; len <= d && len * 2 <= i && x >= sum[i] - sum[i - len]; len++)if (x >= sum[i - len] - sum[i - 2 * len]){dp[i][0] = min(dp[i][0], dp[i - 2 * len][1] + 1);dp[i][1] = min(dp[i][1], dp[i - 2 * len][0] + 1);}return dp[n][!(m & 1)] <= m - 1;}int main(int argc, char const *argv[]){scanf("%d", &T);while (T--){scanf("%d%d%d", &n, &m, &d);sum[0] = 0;for (int i = 1; i <= n; i++)scanf("%d", init + i), sum[i] = sum[i - 1] + init[i];if ((n & 1) || (n < 2 * (m - 1)) || n > 2 * (m - 1)*d) printf("BAD\n");else{int L = 1, R = sum[n], mid;while (L < R){mid = (L + R) / 2;if (check(mid)) R = mid;else L = mid + 1;}printf("%d\n", L);}}return 0;}


N个数,分成m-1段,每段长度不超过2*d,求所有半段中,最大重量的最小值。

最大重量最小值,典型二分题,根据最小值x进行dp,最大不超过x进行分段,dp[i][2]表示前i个符合要求的最小段数,小于m-1则可以。

奇偶分开便于dp

0 0
原创粉丝点击