To host a regional contest like NWERC a lot ofpreparation is necessary: organizing rooms andcomputers, making a good problem set, invitingcontestants, designing T-shirts, booking hotelrooms and so on. I am responsible for goingshopping in the supermarket.
When I get to the cash register, I put all myn items on the conveyor belt and wait until allthe other customers in the queue in front of meare served. While waiting, I realize that thissupermarket recently started to round the totalprice of a purchase to the nearest multiple of 10cents (with 5 cents being rounded upwards). Forexample, 94 cents are rounded to 90 cents, while95 are rounded to 100.
It is possible to divide my purchase into groups and to pay for the parts separately. I managed tofind d dividers to divide my purchase in up to d + 1 groups. I wonder where to place the dividers tominimize the total cost of my purchase. As I am running out of time, I do not want to rearrange itemson the belt.
Input
The input file contains several test cases, each of them as described below.
The input consists of:
• one line with two integers n (1 ≤ n ≤ 2000) and d (1 ≤ d ≤ 20), the number of items and thenumber of available dividers;
• one line with n integers p1, . . . , pn (1 ≤ pi ≤ 10000 for 1 ≤ i ≤ n), the prices of the items incents. The prices are given in the same order as the items appear on the belt.
Output
For each test case, output the minimum amount of money needed to buy all the items, using up to ddividers.
Sample Input
5 1
13 21 55 60 42
5 2
1 1 1 1 1
Sample Output
190
0
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
using namespace std;
#define INF 0x3f3f3f3f
int p[2048];
int sum[2048];
int dp[2048][22];
int main()
{
int n,d;
while(cin>>n>>d)
{
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++)
{
cin>>p[i];
sum[i] += sum[i-1]+p[i];
}
memset(dp,INF,sizeof(dp));
for(int i=1;i<=n;i++)
{
//前i个元素用0个隔板隔开dp[i][0];
dp[i][0] = (sum[i]+5)/10*10;
for(int j=1;j<i;j++)
{
for(int k=1;k<=d;k++)
{
//前i个元素用k个隔板隔开dp[i][k];
//前j个元素用(k-1)个隔板隔开dp[j][k-1];
//区间[j+1,i]的和即(sum[i]-sum[j]+5)/10*10;
dp[i][k]=min(dp[i][k],dp[j][k-1]+(sum[i]-sum[j]+5)/10*10);
}
}
}
//求最小花费
int result = INF;
for(int i=0;i<=d;i++)
result = min(result,dp[n][i]);
cout<<result<<endl;
}
}