思路:分隔式dp
dp[i][j]表示长度到i的分隔次数为j的所能获得的最小值。
这样我们从0到d枚举切割次数。
对于当前的i我们有两个状态:
1.在它前面使用一次切割。此时dp[i][j]=(dp[i-1][j-1]+5)/10*10+p[i];
2.不使用切割。此时dp[i][j]=dp[i-1][j]+p[i];
然后取两者的最小值。
#include <bits/stdc++.h>
using namespace std;
const int MAXN=2000+5;
const int inf=0x3f3f3f3f;
int p[MAXN];
int dp[MAXN][30];
int ans;
int n,d;
int main()
{
while(~scanf("%d%d",&n,&d))
{
memset(dp,0,sizeof(dp));
for(int i=1; i<=n; i++)
{
scanf("%d",&p[i]);
dp[i][0]=p[i];
dp[i][0]+=dp[i-1][0];
}
for(int j=1; j<=d; j++)
for(int i=1; i<=n; i++)
{
dp[i][j]=inf;
if(dp[i-1][j-1])
dp[i][j]=min(((dp[i-1][j-1]+5)/10)*10+p[i],dp[i][j]);
if(dp[i-1][j])
dp[i][j]=min(dp[i-1][j]+p[i],dp[i][j]);
}
int MIN=inf;
for(int i=0; i<=d; ++i)
{
MIN=min(MIN,(dp[n][i]+5)/10*10);
}
printf("%d\n",MIN);
}
return 0;
}