目录
1.部分背包问题
2.排队接水
3.线段覆盖(ddl问题)
4.小A的糖果
5.删数问题
6.陶陶摘苹果(升级版)
7.跳跳!
P2240 【深基12.例1】部分背包问题 - 洛谷 | 计算机科学教育新生态
https://www.luogu.com.cn/problem/P2240
看题目以为是背包 其实是贪心 反证法证明贪心
所有金币都可以分开,也就是说只要按照性价比最高的取一定得到的价值最大。
性价比就是这堆金币的价值除以重量。
只需要把这n堆金币按性价比排序就行了。
然后依次遍历,如果背包中剩余可以拿的重量大于等于这堆金币的重量,就全拿,否则直接装满。
#include
using namespace std;
struct coin{
int m,v;
}a[999];
bool cmp(coin x,coin y){
return x.v*y.m>y.v*x.m;
}
int main(){
int n,t,i;
float ans=0;
cin>>n>>t;
for(int i=0;i>a[i].m>>a[i].v;
}
sort(a,a+n,cmp);
for(i=0;it)
break;
t-=a[i].m;
ans+=a[i].v;}
if(i
P1223 排队接水 - 洛谷 | 计算机科学教育新生态 https://www.luogu.com.cn/problem/P1223
贪心策略:先让用时少的人去接水
画图找规律:sum+=i*p[n-i].time
#include
using namespace std;
struct water{
int num,time;
}p[9999];
bool cmp(water a,water b){
if(a.time!=b.time)
return a.time>n;
for(int i=1;i<=n;i++){
cin>>p[i].time;
p[i].num=i;
}
sort(p+1,p+n+1,cmp);
for(int i=1;i<=n;i++){
cout<
P1803 凌乱的yyy / 线段覆盖 - 洛谷 | 计算机科学教育新生态 https://www.luogu.com.cn/problem/P1803
在一个数轴上有n条线段,现要选取其中k条线段使得这k条线段两两没有重合部分,问最大的k为多少。
最左边的线段放什么最好?
显然放右端点最靠左的线段最好,从左向右放,右端点越小妨碍越少
其他线段放置按右端点排序,贪心放置线段,即能放就放
#include
using namespace std;
struct Match{
int start;
int end;
}c[999999];
bool cmp(Match a,Match b){
return a.end>n;
for(int i=0;i>c[i].start>>c[i].end;
}
sort(c,c+n,cmp);
int x=0;//x代表当前位置
int cnt=0;
for(int i=0;i
P3817 小A的糖果 - 洛谷 | 计算机科学教育新生态 https://www.luogu.com.cn/problem/P3817
当相邻的两盒大于x到时候,应该先吃那一盒呢?
答案:正着遍历,吃后面;反着遍历,吃前面(一举两得 符合至少的要求)
#include
using namespace std;
int a[99999999];
int main(){
int n,x;
cin>>n>>x;
long long ans=0;
for(int i=0;i>a[i];
}
for(int i=0;ix){
ans+=a[i+1]+a[i]-x;
a[i+1]=x-a[i];
}
}
cout<
P1106 删数问题 - 洛谷 | 计算机科学教育新生态 https://www.luogu.com.cn/problem/P1106
#include
using namespace std;
string n;
int k;
string shanchu(int x){
string s;
for(int i=0;i>n;
cin>>k;
int cnt=0;
int i=0;
while(1){
if(n[i]>n[i+1]){
n=shanchu(i);
check(n);
i=0;
cnt++;
if(cnt==k)
break;
}
else
i++;
}
for(int i=0;i
P1478 陶陶摘苹果(升级版) - 洛谷 | 计算机科学教育新生态 https://www.luogu.com.cn/problem/P1478
这种题和1、2、3题一样 先struct写性质 在写sort中cmp(排序规则)然后模拟+贪心
#include
using namespace std;
struct apple{
int xi,yi;
}ap[99999];
bool cmp(apple x,apple y){
return x.yi>n>>s>>a>>b;
for(int i=1;i<=n;i++){
cin>>x1>>y1;
if(x1<=a+b){
cnt++;
ap[cnt].xi=x1;
ap[cnt].yi=y1;
}
}
sort(ap+1,ap+1+cnt,cmp);
for(int i=1;s>=ap[i].yi&&i<=cnt;i++){
ans++;
s-=ap[i].yi;
}
cout<
P4995 跳跳! - 洛谷 | 计算机科学教育新生态 https://www.luogu.com.cn/problem/P4995
贪心策略:最大最小之间来回跳
#include
using namespace std;
long long n,a[310],ans;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+n+1);
int q=0,p=n;
a[0]=0;
while(q