题目描述
有三堆书,分别有i,j,k本,已知每堆书从下到上各本书的重量,每次搬书只能从任意一堆的最上面取,请你设计一个方案,使得花费的力气最大。
每次取书体力消耗都会加大,这里用体力系数表示,取第一本书时,体力系数为1 ,第二本时为2,依次类推,而每次体力消耗值为体力系数和书的重量之积。
图例最累的取书方式为:31+92+23+104=67
【输入格式】
第一行为3个数,分别为i,j,k
第二行到第四行分别为每堆从下到上每本书的重量
【输出格式】
输出最累方式的体力消耗总值
【输入样例】
3 2 4
2 3 2
1 5
9 8 7 4
【输出样例】
257
【数据规模】
对于40%的数据有:
0<=i<100<=j<100<=k<j0<=i<10 0<=j<10 0<=k<j0<=i<100<=j<100<=k<j
对与100%的数据有:
0<=i<1000<=j<1000<=k<1000<=i<100 0<=j<100 0<=k<1000<=i<1000<=j<1000<=k<100
最后输出的体力消耗总值在long int 范围之内
题解:
动态规划(实际是暴力 )
f[i][j][k]f[i][j][k]f[i][j][k] 表示第一堆剩下i本,第二堆剩下j本,第三堆剩下k本所消耗的体力最大值。
因为已知i,j,ki,j,ki,j,k,则第几次搬运也可轻松求得:i+j+ki+j+ki+j+k,不需要四维。
Code:Code:Code:
#include<bits/stdc++.h>
#define N 105
using namespace std;
int a[N],b[N],c[N],f[N][N][N];//数据小不会爆
int n,m,t;
int main()
{
scanf("%d%d%d",&n,&m,&t);
for(int i=n;i>=1;i--)scanf("%d",&a[i]);//因为是从上往下输入数据
for(int i=m;i>=1;i--)scanf("%d",&b[i]);
for(int i=t;i>=1;i--)scanf("%d",&c[i]);
for(int i=0;i<=n;i++)//拿书是从上往下
for(int j=0;j<=m;j++)
for(int k=0;k<=t;k++)
{//注意i,j,k必须>=1才可以拿书
if(i>=1)f[i][j][k]=max(f[i][j][k],f[i-1][j][k]+a[i]*(i+k+j));
if(j>=1)f[i][j][k]=max(f[i][j][k],f[i][j-1][k]+b[j]*(i+k+j));
if(k>=1)f[i][j][k]=max(f[i][j][k],f[i][j][k-1]+c[k]*(i+k+j));
}
printf("%d\n",f[n][m][t]);
return 0;
}
博客探讨了一个关于三堆书的问题,目标是找到一种取书方式,使花费的力气最大。每次只能从任意一堆的最上面取书,且随着取书次数增加,体力消耗系数递增。博客提供了输入输出格式、样例及数据规模,并通过动态规划方法(实际上是暴力求解)求解出最大体力消耗值。最后展示了代码实现。

427

被折叠的 条评论
为什么被折叠?



