您的位置:首页 > 其它

BestCoder 1st Anniversary ($) Souvenir 动态规划

2015-07-25 22:24 337 查看

Souvenir

Accepts: 1186

Submissions: 2743

Time Limit: 2000/1000 MS (Java/Others)

Memory Limit: 262144/262144 K (Java/Others)

Problem Description

Today is the 1st anniversary of BestCoder. Soda, the contest manager, wants to buy a souvenir for each contestant. You can buy the souvenir one by one or set by set in the shop. The price for a souvenir is

yuan and the price for a set of souvenirs if q 
yuan. There's m 
souvenirs in one set.

There's n 
contestants in the contest today. Soda wants to know the minimum cost needed to buy a souvenir for each contestant.

Input

There are multiple test cases. The first line of input contains an integer

(1≤T≤10 5 ) ,
indicating the number of test cases. For each test case:

There's a line containing 4 integers
n,m,p,q 
(1≤n,m,p,q≤10 4 ) .

Output

For each test case, output the minimum cost needed.

Sample Input

2
1 2 2 1
1 2 3 4


Sample Output

1
3
Hint
For the first case, Soda can use 1 yuan to buy a set of 2 souvenirs.
For the second case, Soda can use 3 yuan to buy a souvenir.

题目大意是说:有一种商品,可以单个购买,也可以成组购买,问买n个最低价格。

最暴力的解法就是枚举每一种组合,计算总价取最低,但是效率太低,这里我们使用动态规划。

1.数组res[i].lowcost表示买i件商品的最低价格,因为不要求正好买i个,所以虽然价格最低,但可能多余i个,res[i].left表示多出来的部分

2.如果要购买i个商品,可以选择使用套餐或者不使用套餐,我们当然是选取其中价格更低的,根据i和m的大小,分为两种情况:

   (1)i>m 如果不使用套餐,需要的价格为res[i-m].lowcost+m*p,使用套餐的价格为res[i-m].lowcost+q

   (2)i<=m 不使用套餐为i*p,不使用套餐为q

#include <iostream>
#define MAX 10010
using namespace std;

struct good
{
long long lowcost;
int left;
};

int main()
{
good res[MAX];
int n,m,p,q;
int t;
cin>>t;
while(t--)
{
cin>>n>>m>>p>>q;
res[1].lowcost=p;
res[1].left=0;
for(int i=1;i<=n;i++)
{
if(i-m>0)
{
int cmp;
if(m-res[i-m].left>0)
cmp=m-res[i-m].left;
else
cmp=0;
res[i].lowcost=min(res[i-m].lowcost+cmp*p,res[i-m].lowcost+q);
}
else
{
res[i].lowcost=min(i*p,q);
}
//lowcost[i]=min(lowcost[i],(i-m)>0?lowcost[i-m]+q:q);
}
cout<<res
.lowcost<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息