https://ac.nowcoder.com/acm/problem/14526
首先我们每天肯定都是按照价格从低到高买糖果,所以决策只需要关注当前天买了多少个。
f[i][j]代表前i天已经买了j颗糖果的最小花费,枚举第i天买了多少糖果。
f[i][j] = min(f[i-1][k] + sum[i][i-k] + (j-k)*(j-k)); (k从i-m到i-1枚举)
#include<iostream>
#include<string>
#include<math.h>
#include<algorithm>
#include<vector>
//#include<bits/stdc++.h>
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f;
typedef long long ll;
ll gcd(ll a, ll b)
{
return b ? gcd(b, a % b) : a;
}
ll lcm(ll a, ll b) {
return a * b / (gcd(a, b));
}
#define PII pair<int,int>
using namespace std;
const int N = 2e6 + 10, mod = 1e9 + 7;
int qmi(int a, int k, int p) //快速幂模板
{
int res = 1;
while (k)
{
if (k & 1) res = (ll)res * a % p;
k >>= 1;
a = (ll)a * a % p;
}
return res;
}
///
int dp[1005][1005];
int s[1005][1005];
int main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
cin >> s[i][j];
sort(s[i] + 1, s[i] + 1 + m);
for (int j = 1; j <= m; j++)
s[i][j] += s[i][j - 1];
}
memset(dp, inf, sizeof(dp));
dp[0][0] = 0;
for(int i=1;i<=n;i++)
for(int j=i;j<=min(i*m,n);j++)
for (int k = i - 1; k <= j; k++) {
dp[i][j] = min(dp[i][j], dp[i - 1][k] + s[i][j - k] + (j - k) * (j - k));
}
cout << dp[n][n] << endl;
return 0;
}