1278:【例9.22】复制书稿(book)

复制书稿

下面这个只能拿70分。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 const int N=505;
 7 int a[N],f[N][N],t[N][N],b[N];
 8 
 9 int main(){
10     int m,k;
11     cin>>m>>k;
12     memset(f,127,sizeof(f));
13     //a[i]表示从第一本书抄到第i本书所用时间
14     for(int i=1;i<=m;i++){
15         cin>>a[i];
16         f[i][1]=a[i]+=a[i-1];
17     }
18     //f[i][j]表示前i本书j个人进行抄写
19     for(int i=2;i<=m;i++)
20         for(int j=2;j<=k&&j<=i;j++){
21             t[i][j]=i-1;
22             for(int l=j-1;l<i;l++){
23                 int tmp=max(f[l][j-1],a[i]-a[l]);
24                 if(tmp<f[i][j]||(tmp==f[i][j]&&t[i][j]>l)){
25                     f[i][j]=tmp;
26                     t[i][j]=l;
27                 }
28             }   
29         }
30     //回溯
31     int r=m,c=k,len=1;
32     b[0]=m+1;
33     while(c){
34         r=t[r][c--];
35         b[len++]=r+1;
36     }
37     for(int i=len-1;i>0;i--){
38         cout<<b[i]<<" "<<b[i-1]-1<<endl;
39     }
40     return 0;
41 }

 改善了一下递归输出后,又多了个运行错误。┭┮﹏┭┮

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 const int N=505;
 7 int a[N],f[N][N],t[N][N];
 8 
 9 void print(int e,int d){
10     if(d==1){
11         cout<<"1 "<<e<<endl;
12         return;
13     }
14     int mid=t[e][d];
15     print(mid,d-1);
16     cout<<mid+1<<" "<<e<<endl;
17 } 
18 int main(){
19     int m,k;
20     cin>>m>>k;
21     memset(f,127,sizeof(f));
22     //a[i]表示从第一本书抄到第i本书所用时间
23     for(int i=1;i<=m;i++){
24         cin>>a[i];
25         f[i][1]=a[i]+=a[i-1];
26     }
27     //f[i][j]表示前i本书j个人进行抄写
28     for(int i=2;i<=m;i++)
29         for(int j=2;j<=k&&j<=i;j++){
30             t[i][j]=i;
31             for(int l=j-1;l<i;l++){
32                 int tmp=max(f[l][j-1],a[i]-a[l]);
33                 if(tmp<f[i][j]||(tmp==f[i][j]&&t[i][j]>l)){
34                     f[i][j]=tmp;
35                     t[i][j]=l;
36                 }
37             }   
38         }
39     //回溯
40     print(m,k);
41     return 0;
42 }

 下面的题解来自于https://blog.csdn.net/zqhf123/article/details/105808471(其内容和教材上基本是一模一样,但是我懒得码了(#^.^#))

思路还是一致的(但是我的估计有细节错误。。。)、

它的输出采用的是遍历查找输出,即从后面开始按最大限度分配抄写(小于等于f[m][k]的最大值)

 1 #include<iostream>
 2 #include<cstdio>
 3 #define INF 0X3F3F3F3F
 4 #define N 501
 5 using namespace std;
 6 int i,j,x,y,m,n,k,t,l;
 7 int a[N];//存储每本书的页数
 8 int f[N][N];//f[i][j]表示前i本书分给j个人抄写的最短复制时间
 9 int d[N];//d[j]表示前j本书的总页数
10 int print(int i,int j)
11 {
12     int t,x;
13     if(j == 0) return 0;
14     if(j == 1) 
15     {
16         cout << 1 << " " << i << endl;
17         return 0;
18     }
19     t = i;
20     x = a[i];
21     while(x+a[t-1] <= f[m][k])
22     {
23         x = x + a[t-1];
24         t--;
25     }
26     print(t-1,j-1);
27     cout << t << " " << i << endl;
28 }
29 int main()
30 {
31     cin >> m >> k;
32     for(i = 0;i <= 500;i++)
33     {
34         for(j = 0;j <= 500;j++)
35         {
36             f[i][j] = INF;//对f[i][j]进行初始化 
37         }
38     }    
39     for(i = 1;i <= m;i++)
40     {
41         cin >> a[i];
42         d[i] = d[i-1] + a[i];
43         f[i][1] = d[i];//把前i本书都分给1个人抄写需要的最短时间 
44     }
45 
46     for(j = 2;j <= k;j++)//j个人  
47     {
48         for(i = 1;i <= m;i++)//i本书 
49         {
50             for(l = 1;l <= i-1;l++)//最后一个人抄写的页数
51             {
52                 if(max(f[i-l][j-1],d[i]-d[i-l]) < f[i][j])
53                     f[i][j] = max(f[i-l][j-1],d[i]-d[i-l]);
54             } 
55         }
56     }
57     print(m,k);
58 } 

 

posted @ 2021-08-22 12:27  Rekord  阅读(564)  评论(0编辑  收藏  举报