dp[i][j]的状态为前i天,买了j个糖果的最小花费
题目说每天最少要有一个糖果吃,那么第i天最少要有i个糖果,最多要有min(n,im),n为天数,im为当天生产的糖果总数,
那么dp[i][j]=min(dp[i][j],dp[i-1][k]+C) k>=i-1,j>=i含义就是如果当天不选那么当天最少要有i个糖,选的话,要选几个呢?这要看i-1天选了几个。 只有我们每次都花费最小的糖果,总花费才小,所以我们可以先把每一天的花费从小到大排个序,用前缀和预处理一下。

#include<bits/stdc++.h>
using namespace std;
const int maxn=310;
int arr[maxn][maxn];
long long  dp[maxn][maxn];
long long sum[maxn][maxn];
int main(){
    int n,m;
    cin>>n>>m;
    memset(sum,0,sizeof(sum));
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>arr[i][j];
        }
        sort(arr[i]+1,arr[i]+m+1);
        for(int j=1;j<=m;j++){
            sum[i][j]=sum[i][j-1]+arr[i][j];
        }
    }
    memset(dp,0x3f,sizeof(dp));
    dp[0][0]=0;
    for(int i=1;i<=n;i++){
        for(int j=i;j<=min(n,i*m);j++){
            for(int k=i-1;k<=min(n,(i-1)*m)&&k<=j;k++){
                dp[i][j]=min(dp[i][j],dp[i-1][k]+sum[i][j-k]+(j-k)*(j-k));
            }
        }
    }
    cout<<dp[n][n];
    return 0;
}