猪年快乐!在这个快乐的日子里我们当然要去超市买可乐喝啦!
现在超市有n种可乐,第 i 种可乐的价格为C[i] ,体积为 2i-1 毫升,每种可乐都是无限供应的 ,现在你想买至少 L毫升的可乐 ,作为一个省钱小能手,聪明的你能够想到最少要花多少钱吗?
输入包含多组测试用例。
每组测试用例第一行包含两个数字 n 和 L (1?≤?n?≤?30; 1?≤?L?≤?109) , n是可乐的种类数, L是我们最终要买的可乐体积。
第二行包含 n 个数字 C1,C2,...Cn n (1?≤?ci?≤?109) ,代表每一种可乐的价格。
输出一个数字 , 购买至少L毫升的可乐需要的最少花费。
4 12
20 30 70 90
4 3
10000 1000 100 10
4 3
10 100 1000 10000
150
10
30
这道题第一眼看上去有点像完全背包问题,仔细思考之后就会发现还是有不同的地方,背包问题的背包空间大小是确定的。但是这道题没有说不可以多买可乐,求至少购买L毫升,也可以比L毫升多也行。这题是用贪心去做。肯定是买物美价廉的东西。先把每种可乐的每毫升单价算出来,一开始就买单价小的买,如果需要购买的可乐体积比这种可乐的体积小。这有两种情况可以选择,一是选择直接再买一瓶这种可乐,多了体积也没关系只要价钱低就好,第二种在剩下可乐中购买剩下体积的可乐,那种方法的钱少就用那种方法。(==这题要用long long去做,用int会溢出)==
上代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long L, V[32], cost[32];
int n;
int vis[32];
int in[32];
double c[32];
bool cmp(int a, int b)
{
if(c[a] < c[b]) return true;
else return false;
}
long long tanxin(long long l)
{
long long an, tem;
for(int i = 0; i < n; i++)
{
if(vis[in[i]])
{
continue;
}
if(l % V[in[i]] == 0)
{
an = (l / V[in[i]]) * cost[in[i]];
return an;
}
else
{
an = (l / V[in[i]]) * cost[in[i]];
vis[in[i]] = 1;
tem = tanxin(l - (l / V[in[i]]) * V[in[i]]);
if( tem > cost[in[i]] )
an = an + cost[in[i]];
else
an = an + tem;
return an;
}
}
}
int main()
{
V[0] = 1;
for(int i = 1; i < 32; i++)
V[i] = V[i-1]*2;
while(scanf("%d %lld", &n, &L) != EOF)
{
for(int i = 0; i < n; i++)
{
scanf("%lld", &cost[i]);
c[i] = cost[i]*1.0/V[i];
in[i] = i;
}
sort(in, in+n, cmp);
memset(vis, 0, sizeof(vis));
printf("%lld\n", tanxin(L));
}
return 0;
}
原文:https://www.cnblogs.com/Mrs-Jiangmengxia/p/12531617.html