贪心刷题(5日计划)第三天

- P2909 [USACO08OPEN]Cow Cars S

在这里插入图片描述

思路

一开始我是这么想的,先给牛的速度排序,然后再根据速度把每头牛依次放到每个道上去。
但有一种更好的方法:排序+统计。就是依次统计每条道上可以放几头牛。

源码

#include<bits/stdc++.h>

using namespace std;

int s[50005];
int main(){
	int n,m,d,l;//n头牛,m条道,d表示单位,l最低速度

	cin>>n>>m>>d>>l;
	for(int i=0;i<n;i++)
		cin>>s[i];
	sort(s,s+n);
	int sum=0;//计算牛的数量 
	int ans=0;//枚举每条道上,前面的牛数。 
	for(int i=0;i<m;i++){
		ans=0;
		for(int j=0;j<n;j++){
			if(!s[j])  continue;
			if(    s[j]-d*ans>=l  ||   (s[j]-d*ans<0&&l==0) ){    //l为0,则所有牛都能放
				sum++;
				ans++;
				s[j] = 0;
			}
		} 
	}
	cout<<sum<<endl;
	return 0;
} 

- P1252 马拉松接力赛

在这里插入图片描述

思路

求最短时间,就是计算每多跑1km,那个运动员花的时间最少。

源码

#include<bits/stdc++.h>

using namespace std;
int a[5][11],b[5][11];
int c[5];
int flag,ans;
int main(){
	for(int i=0;i<5;i++)
		c[i]=1;
	for(int i=0;i<5;i++){
		for(int j=1;j<11;j++){
			cin>>a[i][j];
			b[i][j]=a[i][j]-a[i][j-1];  //计算时间差,用于计算时间最小值 
		}
	}
	for(int i=0;i<20;i++){
		int minn=1000000009;
		for(int j=0;j<5;j++){
			if(b[j][c[j]+1]<minn&&c[j]+1<=10){
				flag=j;      //flag用于标记,当前最短时间是那个人 
				minn=b[j][c[j]+1];
				
			}
		}
		c[flag]++;
	}
	for(int i=0;i<5;i++){
		ans+=a[i][c[i]];
	}
	cout<<ans<<endl;
	for(int i=0;i<5;i++)
		cout<<c[i]<<" ";	
}

- P1515 旅行

在这里插入图片描述

思路

先排序,再用搜索来计算次数。

源码

#include<bits/stdc++.h>
using namespace std;
    //              已经有的旅馆列表:
int a[40]={0,990,1010,1970,2030,2940,3060,3930,4060,4970,5030,5990,6010,7000};
int c,b,n,ans;
void dfs(int k)//k:第k个旅馆 
{
	if(k==n){
		ans++;
		return ;
	}
	for(int i=k+1;i<=n;i++){
		if(a[i]-a[k]>=c&&a[i]-a[k]<=b){
			dfs(i);
		}
	}

}
int main()
{
	cin>>c>>b>>n;
	for(int i=14;i<n+14;i++)
		cin>>a[i];
	n=n+14;
	sort(a,a+n+1);    //给n个数排序。
	dfs(0);
	cout<<ans<<endl;
	
}

思路2

1.一个数组储存所有旅馆,初始化时先存下前面14个旅馆。
2.输入新添加旅馆后,将所有旅馆排序,方便日后比较。
3.根据斐波那契数列,如果可以从A点走到B点,那么A点的总方案数应该加上B点的方案数。
4.循环进行3操作即可(但B点只需要是A点前面的点)。

源码

//刚开始的地方也算,一种方案。
#include<bits/stdc++.h>//超级万能头
using namespace std;
int a,b,n,ans[40],r[40]={0,990,1010,1970,2030,2940,3060,3930,4060,4970,5030,5990,6010,7000};
//旅馆初始化 
int main(){
	scanf("%d %d %d",&a,&b,&n);
	for (int i=14;i<14+n;i++) cin>>r[i];//输入 
	sort(r,r+14+n);//排序 
	ans[0]=1; //起始点默认一套方案 
	for (int i=1;i<14+n;i++){//枚举所有点 
		for (int j=0;j<i;j++){//枚举这个点之前的点 
			if (r[i]-r[j]>=a&&r[i]-r[j]<=b){//如果这两个点之间的距离符合要求 
				ans[i]+=ans[j];//这个点可以获得前面那个点的所有可能 
			}
		}
	}
	cout<<ans[13+n]<<endl;//输出到终点时的所有可能 
	return 0;//好习惯不可忘
}

- P2695 骑士的工作

在这里插入图片描述

思路

排序+判断

源码

#include <stdio.h>
#include<iostream>
#include <algorithm>//sort头
using namespace std;

int main () {
    int qs[20010],el[20010],m,n,i,ans=0;
    cin>>n>>m;
	for (i=0;i<n;i++) cin>>el[i];//读入,不必多说
	for (i=0;i<m;i++) cin>>qs[i];
	sort (el,el+n);//排序
	sort (qs,qs+m);//排序
	if (n>m) {//如果恶龙数大于骑士的数量,则输出you died!
		printf ("you died!");
		return 0;
	}
	int j=0;
	for (i=0;i<n;i++) {//枚举答案
		while (el[i]>qs[j]) j++;//找到最小一个大于该头的骑士
		ans+=qs[j];//累加答案
		if (j>m-1) break;
		j++;
	}
	if (i!=n) 
		printf ("you died!");//输出答案
	else
		printf ("%d\n",ans);
	return 0;//好轻松的呢!!!
}

- P1376 [USACO05MAR]Yogurt factory 机器工厂在这里插入图片描述

思路

首先需要想明白一点,委托人需要多少机器,并不意味着每周要生产多少机器。
若上一周的价格比这周的便宜,则可以让上周多生产一点。
若本周便宜,则只需要本周进行生产就行。
继续判断,则需要本周的价格与先前最小的价格判断。

源码

#include<iostream>
using namespace std;
int main()
{
	//就是交付完这些机器要花多少钱,多生产不用管。 
	//这样理解:第一周因为是刚生产则直接卖出,但制造的机器可以大于需要的
	// 
    int c,y;
    long long n,ans=0;
    int s,lastweek;
    cin>>n>>s;    
    for(int i=1;i<=n;i++)
    {
        cin>>c>>y;    //一台机器的价格,需要交付的机器 
        if(i==1) lastweek=c;    //上一星期每台机器要花的钱 
        else lastweek=min(lastweek+s,c);   // 上星期与这个星期的比较 
        ans+=lastweek*y;//那个便宜就选哪种方案 
    }
    cout<<ans;
    //system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ღ江晚吟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值