2017.12.03
贪心
1.金银岛
思路:既然每一种金属都是可以任意切割的,那么就可以先求出每一种金属的单位价值,把它进行排序,从单位价值最大的开始装起,只要背包还有空间就全部装进背包,如果装不完就把剩下的空间全部装这种物体。
核心代码:
1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 double gold[1001][4]; 5 int main(){ 6 int zs; 7 double max=0; 8 int i,j; 9 scanf("%d",&zs); 10 for(int k=1;k<=zs;k++){ 11 int w=0; 12 double s; 13 max=0; 14 scanf("%d%lf",&w,&s); 15 for(i=1;i<=s;i++){ 16 scanf("%lf%lf",&gold[i][1],&gold[i][2]); 17 gold[i][3]=gold[i][2]/gold[i][1]; 18 } 19 for(i=1;i<s;i++){ 20 int sortmax=i; 21 for(j=i+1;j<=s;j++){ 22 if(gold[sortmax][3]<gold[j][3]) 23 sortmax=j; 24 } 25 if(sortmax!=i){ 26 double t; 27 t=gold[i][1];gold[i][1]=gold[sortmax][1];gold[sortmax][1]=t; 28 t=gold[i][2];gold[i][2]=gold[sortmax][2];gold[sortmax][2]=t; 29 t=gold[i][3];gold[i][3]=gold[sortmax][3];gold[sortmax][3]=t; 30 } 31 } 32 for(i=1;i<=s&&w>0;i++){ 33 if(w>=gold[i][1]){ 34 w-=gold[i][1]; 35 max+=gold[i][2]; 36 } 37 else if(w<gold[i][1]){ 38 max+=gold[i][3]*w; 39 w=0; 40 } 41 } 42 printf("%.2f\n",max); 43 } 44 return 0; 45 }
状态:AC
思路:要求最小的与题中所给的数I转换成为二进制后所含‘1’的数目相同,就可以先用一个常量保存I的含‘1’值,从I+1开始,每次都判断一下它的含‘1’数量是否和I相等,就可以求出最小的数。
核心代码:
1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 int wen(int k){ 5 int one=0; 6 while(k){ 7 if(k%2==1)one++; 8 k/=2; 9 } 10 return one; 11 } 12 int main(){ 13 int n; 14 scanf("%d",&n); 15 while(n){ 16 for(int i=n+1;;i++){ 17 if(wen(n)==wen(i)){ 18 printf("%d\n",i); 19 break; 20 } 21 } 22 scanf("%d",&n); 23 } 24 }
状态:AC
思路:首先他如果是一定要跟一个人,那么在他以前出发的人就可以不再考虑。再输入完后就可以去掉。再者,既然他会总是不断跟着最快的人,可以直接扫一遍,选出时间最短的那个人,它所用的时间就是那个人所用的时间。
核心代码:
1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 double v,t,m; 5 int main(){ 6 int n; 7 scanf("%d",&n); 8 while(n){ 9 double minn=1000000; 10 for(int i=1;i<=n;i++){ 11 scanf("%lf%lf",&v,&t); 12 if(t>=0){ 13 m=4.5/v*3600+t; 14 if(m<minn)minn=m; 15 } 16 } 17 printf("%d\n",int(minn+0.99)); 18 scanf("%d",&n); 19 } 20 return 0; 21 }
状态:AC
4.书架
思路:既然要用最少的牛数,那每第i次选择,肯定要选剩下的牛中最高的。即扫一遍排序后从大的选起。与金银岛类似。
核心代码:
1 //为了用sort函数偷懒,学C语言的博主决定用C++ 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 using namespace std; 8 int main(){ 9 int n,a[21000],t=0; 10 long long s=0,b; 11 cin>>n>>b; 12 for(int i=1;i<=n;i++) 13 cin>>a[i]; 14 sort(a+1,a+n+1); 15 for(int i=n;i>=1;i--){ 16 s=s+a[i]; 17 t++; 18 if(s>=b){ 19 cout<<t; 20 break; 21 } 22 } 23 return 0; 24 }
状态:AC
5.装箱问题
思路:从最大的6*6箱子装起,先装大的,再装小的(在一个大箱子里也遵循这个原理)。可以画图来模拟一下,特别要注意3*3箱子是有多种方法放置的。最后用can1,can2来表示可以装1*1,2*2箱子的数量。
核心代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int a1,a2,a3,a4,a5,a6,sum,can1,can2; 4 int main(){ 5 cin>>a1>>a2>>a3>>a4>>a5>>a6; 6 while (a1+a2+a3+a4+a5+a6!=0){ 7 sum=0; 8 can1=0; 9 can2=0; 10 //放6*6 11 sum+=a6; 12 //放5*5 13 sum+=a5; 14 can1+=a5*11; 15 //放4*4 16 sum+=a4; 17 can2+=a4*5; 18 //放3*3 19 sum+=a3/4; 20 a3%=4; 21 if (a3>0){ 22 sum++; 23 if (a3==1) { 24 can1+=7; 25 can2+=5; 26 } 27 else if (a3==2) { 28 can1+=6; 29 can2+=3; 30 } 31 else { 32 can1+=5; 33 can2+=1; 34 } 35 } 36 //放2*2 37 if (a2>can2){ 38 a2-=can2; 39 sum+=a2/9; 40 a2%=9; 41 if (a2>0){ 42 sum++; 43 can1+=(9-a2)*4; 44 } 45 46 }else can1+=(can2-a2)*4; 47 //放1*1 48 if (a1>can1){ 49 a1-=can1; 50 sum+=a1/36; 51 a1%=36; 52 if (a1>0){ 53 sum++; 54 } 55 } 56 cout<<sum<<endl; 57 cin>>a1>>a2>>a3>>a4>>a5>>a6; 58 } 59 return 0; 60 }
状态:AC