您的位置:首页 > 其它

UVALive - 6952 Cent Savings (DP)

2017-02-22 20:32 323 查看
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
[i]);

cout<<result<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp