题意:给出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 }