题意: 小需要储备
天的面包,面包店每天生产
个面包,第
天生产的第
块面包的价格为
,同时,一天购买
块面包需要额外花费
,现在问储备至少
块面包的最低价格是多少。
数据范围:
题解:
分组背包问题。从低价到高价开始选择面包,本题关键是考虑额外的部分。
考虑第天的第
块面包,需要多加
,对于第
块面包,需要多加
,所以对于第
块面包多的价值就是
。所以预处理下第
天的前缀和即可。同时要考虑到每天得有面包吃,所以转移时前一个状态必须从
开始。
时间复杂度:
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>
inline T Read() {
T x = 0, f = 1;
char ch = getchar();
while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
while(isdigit(ch)) {x = (x << 3) + (x << 1) + ch - '0'; ch = getchar();}
return x * f;
}
#define read() Read<int>()
#define readl() Read<long long>()
const int N = 310;
int f[N][N];
int c[N][N];
int main()
{
int n = read(), m = read();
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) c[i][j] = read();
sort(c[i] + 1, c[i] + 1 + m);
c[i][0] = 0;
for(int j = 1; j <= m; j++) c[i][j] += c[i][j - 1] + (2 * j - 1);
}
memset(f, 0x3f, sizeof f);
f[0][0] = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
for(int k = max(i - 1, j - m); k <= j; k++)
f[i][j] = min(f[i][j], f[i - 1][k] + c[i][j - k]);
printf("%d\n", f[n][n]);
return 0;
} 
京公网安备 11010502036488号