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;
}
}
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;
}
}
相关文章推荐
- UVALive - 6952 Cent Savings dp
- UVALive 6592 C - Cent Savings (dp)
- Cent Savings UVALive - 6952
- uva 6952 Cent Savings dp
- C - Cent Savings UVALive - 6952
- uva 6952 Cent Savings dp
- UVALive - 6952 (隔板dp)
- UVALive 4126 Password Suspects(AC自动机 套 DP)
- UVALive 5983 MAGRID(二分+dp)
- uva live4731 蜂窝网络 题解(dp+贪心)
- UVALive 4015 - Caves(树形DP)
- UvaLive 6435 Network Packet Ordering(dp)
- 【UVALive 7505】Hungry Game of Ants(DP)
- UVALive 7271 A Math Problem 【数位dp计数】
- UVALive 6624 - Card Trick - 概率dp
- [UVALive3675]Sorted bit sequence && 数位DP
- UVALive - 3882 And Then There Was One (递推[dp])
- UVALive 3305Tour(双调DP)
- UVaLive 3490 Generator (KMP + DP + Gauss)
- uva live 4394 String painter 区间dp