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 }