P1281 书的复制

题意:给出n本书,每本书有不同页数,给出m个人看这m本书

     答案为这m个人看的页数最多的权值,要求求出最小的权值

思路:区间dp   第一维枚举人数 第二维枚举长度 然后找出最优解即可

        但是:这道题可能有多个解,他要求输出前面的人看书比较少的解

          所以  我一开始还开了第三维去表示得出的答案位置,这样子得出来的答案并不一定是前面的人看书较少的答案

            所以,最后换成了递归来求出最优解的做法

题目中 第三维的0表示权值,1表示位置

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn=5e2+10;
 5 const int inf=0x3f3f3f3f;
 6 int dp[maxn][maxn][2];
 7 int a[maxn];int sum[maxn];
 8 struct node
 9 {
10     int left,right;
11 }G[maxn];
12 void res(int x,int ans)
13 {
14     if(!x) return;
15     for(int i=x;i>=0;i--){
16         if(sum[x]-sum[i-1]>ans|| !i){
17             res(i,ans);
18             printf("%d %d\n",i+1,x);
19             break;
20         }
21     }
22 }
23 int main()
24 {
25     int n,m;
26     scanf("%d%d",&n,&m);
27     memset(dp,inf,sizeof(dp));
28     for(int i=1;i<=n;i++){
29         scanf("%d",&a[i]);
30         sum[i]=sum[i-1]+a[i];
31         dp[i][1][0]=sum[i];
32         dp[i][1][1]=1;
33     }
34     for(int i=2;i<=m;i++){
35         for(int j=1;j<=n;j++){
36           //  dp[j][i][0]=max(dp[j-1][i-1][0],a[j]);
37           //  dp[j][i][1]=j;
38             for(int k=2;k<=j;k++){
39                 int tmp=max(dp[k-1][i-1][0],sum[j]-sum[k-1]);
40                 if(tmp<dp[j][i][0]){
41                     dp[j][i][0]=tmp;
42                     dp[j][i][1]=k;
43                 }
44             }
45         }
46     }
47     int base=n;
48     for(int i=m;i>=1;i--){
49         G[i].left=dp[base][i][1];
50         G[i].right=base;
51         base=dp[base][i][1]-1;
52     }
53    // for(int i=1;i<=m;i++)
54      //   printf("%d %d\n",G[i].left,G[i].right);
55     res(n,dp[n][m][0]);
56     return 0;
57 }
View Code

  

猜你喜欢

转载自www.cnblogs.com/pangbi/p/12592257.html