WZK 的减肥计划(plan.cpp/ plan.in/ plan.out)
问题描述:
WZK 发现他的体重正迅猛的上升着,对此他感到非常焦虑,想要制定出一套完美的减肥计划。
于是 WZK 翻阅资料,查到了各种食品所含的卡路里和价格,并且千辛万苦的测出了自己一天所需的卡路里。
现在有 n 种食品可供 WZK 选择,每种物品都有给定的价格,卡路里和拥有数量,你的任务就是要选出一些食品使得总卡路里大于消耗量且最小,如果有多种组合满足条件,则取价格最小的。
输入格式:
第一行为两个整数 n(0<n<=100), k(0<k<=10^5)分别表示物品个数和一天消耗的最少卡路里。
接下来 n 行每行 3 个整数, costi, mi, cali( 0< costi,cali<10^6,1<=mi<=100)分别表示价格,数量和所含卡路里。
输入数据保证合法、有解。
输出格式:
满足条件的总卡路里和总价格,中间用一个空格隔开。
注意:保证答案的总卡路里小于 10^5,总价格小于 10^8。
输入样例:
5 10
10 2 6
5 1 9
6 1 6
9 1 6
5 1 9
输出样例:
12 15
写循环的时候一直有不祥的预感
但是因为这次题目都还蛮简单所以就非常笨蛋地安慰了自己
不知道出于什么样的心理也没检查剩下的时间就在题目的pdf文件上乱画画
然后果然这题就差点爆零了呢...
反省!
下次绝对认真画
重写的时候发现其实是二进制分割物品写错了...
一直担心的循环反而神奇地没写错
哈哈哈???
而且倒序循环的时候范围又开大了所以还会超时
可能等输入完数据统计最大卡路里再来循环会优化一些
不过我就懒得写了
^^
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int n , k , a , b , c , all; 5 int minn = 100000000 , ans = 100000000 ; 6 int f[100001] ; 7 8 int read(){ 9 char c ; 10 int sign = 1 ; 11 while((c = getchar())<'0'|| c >'9') 12 if(c=='-') sign = -1 ; 13 int Ans = c - '0' ; 14 while((c = getchar())>='0'&& c<='9') 15 Ans = Ans * 10 + c - '0' ; 16 return Ans * sign ; 17 } 18 19 void deal(int a , int b){ 20 for(int i = 100000 ; i >= b ; -- i){ 21 if(f[i] > a + f[i - b]) { 22 f[i] = a + f[i - b] ; 23 if(i > k && ( i < ans || (i == ans && f[i] < minn))) 24 ans = i , minn = f[i] ; 25 } 26 } 27 } 28 29 int main(){ 30 //freopen("plan.in","r",stdin); 31 //freopen("plan.out","w",stdout); 32 n = read() , k = read() ; 33 for(int i = 1 ; i <= 100000 ; ++ i) 34 f[i] = 100000; 35 f[0] = 0 ; 36 for(int i = 1 ; i <= n ; ++ i){ 37 a = read() , b = read() , c = read() ; 38 int two = 1 ; 39 while((b -= two) >= 0){ 40 deal(two * a , two * c) ; 41 two = (two<<1) ; 42 } 43 b += two ; 44 if(b != 0){ 45 deal(b * a , b * c) ; 46 } 47 } 48 cout << ans << ' ' << minn ; 49 return 0 ; 50 }