UVALive 6592 C - Cent Savings (dp)

96 篇文章 0 订阅
51 篇文章 0 订阅

题意:

小明买了n件商品,付钱的时候他可以划分k次付款,每次付款最后一位数都会四舍五入,比如95就是付款100,问在最多划分k次且不改变序列的情况下 ,我们能得到的最小花费


解题思路:

定义dp[i][j]为到第i位的商品划分j次产生的最小花费,

我们枚举划分1到k次的情况,在每最多划分j次的状态,且我们已知划分j-1次的答案,我们就可以枚举的j次划分在哪个位置上,从而得到答案.

转移方程就是dp[i][j]=min(dp[i-1][j]+a[i], (dp[i-1][j-1]+5)/10*10).


代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e4;
const int inf=20000000;
int a[maxn];
int dp[maxn][22];
int main()
{
    int i, j, n, d;
    while(~scanf("%d%d", &n, &d))
    {
       memset(dp, 0, sizeof dp);
       for(i=1; i<=n; i++)
       {
	 scanf("%d", &a[i]);
	 dp[i][0]+=a[i]+dp[i-1][0];
//	 book[b[i]]++;
       }
       int x, y;
	
       for(j=1; j<=d; j++)
       {
	   for(i=1; i<=n; i++)
	   {
	      dp[i][j]=inf;
	      if(dp[i-1][j])
	      {
		 dp[i][j]=min(dp[i-1][j]+a[i], dp[i][j]);
	      }
	      if(dp[i-1][j-1])
	      {
		dp[i][j]=min(dp[i][j], (dp[i-1][j-1]+5)/10*10+a[i]);
	      }
	   }
       }
       int ans=inf;
       for(i=0; i<=d; i++)ans=min(ans, (dp[n][i]+5)/10*10);
       printf("%d\n", ans);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值