书的复制 动规,贪心

题目链接:https://www.luogu.org/problemnew/show/P1281

分析:用dp[i][j]来表示前i个人分j本书所需的最短时间

我们可以利用第三层u来实现状态转移,u用来表示前i-1人抄写的最后一本书

状态转移方程式为:dp[i][j]=min(dp[i][j],max(dp[i-1][u-1],sum[j]-sum[u-1]))   sum数组为前缀和数组

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=1<<30;
const ll maxn=510;
const double pi=acos(-1);
const int mod=10000;
int a[maxn],sum[maxn];
int dp[maxn][maxn];
void print(int x,int ans){
    if(!x)return ;
    for(int i=x;i>=0;i--){
        if(i==0||sum[x]-sum[i-1]>ans){
            print(i,ans);
            printf("%d %d\n",i+1,x);
            break;
        }
    }
}
int main(){
    int m,k;scanf("%d%d",&m,&k);
    fill((int *)dp,(int *)dp+510*510,inf);
    for(int i=1;i<=m;i++){
    scanf("%d",&a[i]);
    sum[i]=sum[i-1]+a[i];
    }
    for(int i=1;i<=m;i++){
        dp[1][i]=sum[i];
    }
    for(int i=2;i<=k;i++){
        for(int j=i;j<=m;j++){
            for(int u=i;u<=j;u++){
                dp[i][j]=min(dp[i][j],max(dp[i-1][u-1],sum[j]-sum[u-1]));
            }
        }
    }
    //cout<<dp[k][m]<<endl;
    print(m,dp[k][m]);
    return 0;
}

 

posted @ 2019-04-11 15:12  清酒令  阅读(211)  评论(0编辑  收藏  举报