poj 1505 copying Books 动态规划 -- 后续处理要细心~

历经不足两天,接近两天,哥终于 A 了你!

题意 : 假设有M本书(编号为1,2,…,M),想将每本复制一份,M本书的页数可能不同(分别是a1,a2,…,aM)。

          任务时将这M本书分给K 个抄写员(K≤M〉,每本书只能分配给一个抄写员进行复制,而每个抄写员所分配到的书必须是连续顺序的。

          要求复制总时间最短, 该如何分配抄写。

用 DP 做的,DP 还算不难,后续的处理挺繁琐。对于我等水平来说,不容易 !

// 方程 : dp[i][j] = min(dp[i][j], max(dp[i-1][v], sum[j]-sum[v])) i 个人 抄写 前j 本书 --> 数据 :  2 7 3 3 5 输出 :2 7 / 3 / 3 5

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <string>

using namespace std;
const int N = 510;
const int INF = 0x7fffffff;
int dp[N][N]; // 方程 : dp[i][j] = min(dp[i][j], max(dp[i-1][v], sum[j]-sum[v])) i 个人 抄写 前j 本书
int sum[N];
int a[N];
int path[N];

int main() {
    int T, m, k, i, j, v;// tmp;
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d", &m, &k);
        for(i = 0; i <= k; i++) {
            for(j = 0; j <= m; j++) {
                dp[i][j] = INF;
            }
        }
        memset(sum, 0, sizeof(sum));
        for(i = 1; i <= m; i++) { /// 书的页数
            scanf("%d", &a[i]);
            sum[i] += (sum[i-1] + a[i]);
            dp[1][i] = sum[i];
        }
        for(i = 2; i <= k; i++) {
            for(j = i; j <= m; j++) {
                for(v = i-1; v <= j; v++) {
                    dp[i][j] = min(dp[i][j], max(dp[i-1][v], sum[j]-sum[v]));
                }
            }
        }
        int ans = dp[k][m];
        int t_sum = 0;
        for(i = m, j = k-1; i >= 1; i--){
            t_sum += a[i];
            if(t_sum > ans || i <= j){
                path[j--] = i+1; // 3 4 5
                t_sum = a[i];
            }
        }
        for(i=j=1; i <= m; i++){
            if(i > 1) printf(" ");
            if(j < k && path[j] == i){
                printf("/ ");
                j++;
            }
            printf("%d", a[i]);
        }
        printf("\n");
    }
    system("pause");
    return 0;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值