PTA 郑州大学2023-2024第一学期算法设计与分析-实验6(第四章)

1. 月饼

贪心就行了

三个东西,一个Pair<int,int>,可以用结构体写。这里自带了排序规则

sort函数,相信应该都知道

reverse,翻转,可以理解为数组头变数组尾,好处是默认排序时可以不指定排序方式,排完reverse即可

#include<bits/stdc++.h>
#define endl "\n"
//#define int long long
#define AC return
#define pleaseqwq 0

using namespace std;

const int N=2e5+10;
typedef pair<double,double>PII;
typedef pair<string,int>PSI;
typedef pair<double,double>pdd;

PII a[N];

signed main(){
	//cin.tie(0),cout.tie(0);
	//ios::sync_with_stdio(false);
	
	int n,d;
    cin>>n>>d;
    for(int i=0;i<n;i++){
        cin>>a[i].second;
    }
    for(int i=0;i<n;i++){
        cin>>a[i].first;
        a[i].first/=a[i].second;
    }
    sort(a,a+n);
    reverse(a,a+n);
    double res=0;
    int cnt=0;
    for(int i=0;i<n;i++){
        if(cnt+a[i].second<d){
            res+=a[i].first*a[i].second;
            cnt+=a[i].second;
        }else{
            res+=(d-cnt)*a[i].first;
            break;
        }
    }
    printf("%.2f",res);
	AC pleaseqwq;
}

2. 汽车加油问题

我是小丑,第一眼还以为是dp,结果就贪心就好了

果然dp是我最差的部分啊,甚至都一眼看不出来不是dp题

贪心就行了

#include<bits/stdc++.h>
//#define int long long
#define endl "\n"

#define fir for(int i=1;i<=n;i++)
#define rif for(int i=n;i>=1;i--)

#define AC return
#define pleaseqwq 0
using namespace std;

typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;

unordered_map<string,int>si;
unordered_map<int,int>ii;


const int N=3e3+10;

int a[N];




signed main(){
	cin.tie(0),cout.tie(0);
	ios::sync_with_stdio(false);
	
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=k+1;i++) cin>>a[i];
	int cnt=0,sum=0;
	bool success=true;
	for(int i=1;i<=k+1;i++){
		if(sum+a[i]<=n) sum+=a[i];
		else{
			if(a[i]>n) success=false;
			else sum=a[i],cnt++;
		}
	}
	if(success) cout<<cnt<<endl;
	else cout<<"No Solution!"<<endl;
	
	AC pleaseqwq;
} 

3 会场安排问题

好像在哪里做过这道题。。

我们以结束时间来判断,判断最早结束时间前是否有多的活动

有的话,就多开会场即可

(好像是牛客?忘了。。。花了一段时间找了找写过的题,没有,但是好熟悉,应该是以前做过类似的题,在哪里忘了)

#include<bits/stdc++.h>
//#define int long long
#define endl "\n"

#define fir for(int i=1;i<=n;i++)
#define rif for(int i=n;i>=1;i--)

#define AC return
#define pleaseqwq 0
using namespace std;

typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;

unordered_map<string,int>si;
unordered_map<int,int>ii;


const int N=3e3+10;

int l[N],r[N];




signed main(){
	cin.tie(0),cout.tie(0);
	ios::sync_with_stdio(false);
	
	int n;
	cin>>n;
	fir cin>>l[i]>>r[i];
	int cnt=0;
	//判断最早结束的活动结束前是否有其它活动
	//有则必须添加场馆,无则不需
	sort(l+1,l+n+1);
	sort(r+1,r+n+1);
	int j=1;
	for(int i=1;i<=n;i++){
		if(r[j]>l[i]) cnt++;
		else j++;
	}
	/*
	我们假设[1,3][2,4][1,4][3,5]四组数据
	直接排序,得到[1,1,2,3]和[3,4,4,5]
	对第一个3来说,最早结束是3,但最早开始时间是1,说明至少要多占用一个会场
	往下走,继续判断,此间最早结束是3,但仍然是1,再多占用
	再往下走,继续判断,最早2,仍然多占用 
	此时占用了三个
	再往下,此时3并不大于3,说明可以紧挨着,那么这个时间就可以放到最早结束的第一个场馆
	然后考察第二个最早结束的时间即可,可以放的话,我们就放他后面,往后同理 
	*/ 
	cout<<cnt<<endl;
	AC pleaseqwq;
} 

4 程序存储问题

简单贪心没必要多说吧。。

#include<bits/stdc++.h>
//#define int long long
#define endl "\n"

#define fir for(int i=1;i<=n;i++)
#define rif for(int i=n;i>=1;i--)

#define AC return
#define pleaseqwq 0
using namespace std;

typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;

unordered_map<string,int>si;
unordered_map<int,int>ii;


const int N=3e3+10;

int a[N];


signed main(){
	cin.tie(0),cout.tie(0);
	ios::sync_with_stdio(false);
	
	int n,l;
	cin>>n>>l;
	fir cin>>a[i];
	sort(a+1,a+n+1);
	int sum=0,cnt=0;
	for(int i=1;i<=n;i++){
		if(sum+a[i]<=l) sum+=a[i],cnt++;
		else break;
	}
	cout<<cnt<<endl;
	AC pleaseqwq;
} 

5 工厂机器安排

翻译:m个任务,第i个花xi时间,难度为yi,低于难度yi或花费时间xi超过工作时长的机器无法完成任务。完成任务得到500xi+2yi的钱。每台机器每天只能完成一个任务,任务只能被完成一次。

求完成任务最多的方案。同种方案下,赚钱多的优先。多组样例。

首先,我们排序的时候一定是尽量完成花费时间久的任务,同时间下难度高的优先

但同时我们要选择能完成的机器中尽量差的机器

换言之,我们需要记录所有能完成任务的机器,在这些机器中从当前任务所需难度往上找,直到能找到能完成的任务。

显然此时任务应当从花费时间长到短排序。

贪心题,难也确实难。

#include<bits/stdc++.h>
#define int long long
#define endl "\n"

#define fir for(int i=1;i<=n;i++)
#define rif for(int i=n;i>=1;i--)

#define AC return
#define pleaseqwq 0
using namespace std;

typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;

unordered_map<string,int>si;
unordered_map<int,int>ii;


const int N=2e5+10;

//m:machine,t:task 
PII machine[N];
PII task[N];

int cnt[N];


//同种情况下,尽量完成花费时间长的,难度大的。
//同时选用最差的能完成的机器 
//可以用重载运算符写 
bool cmp(const PII &a, const PII &b){
	return a.first==b.first?a.second>b.second:a.first>b.first;
} 

signed main(){
	cin.tie(0),cout.tie(0);
	ios::sync_with_stdio(false);
	
	int n,m;
	while(cin>>n>>m){
		for(int i=0;i<n;i++) cin>>machine[i].first>>machine[i].second;
		for(int i=0;i<m;i++) cin>>task[i].first>>task[i].second;
		sort(machine,machine+n,cmp);
		sort(task,task+m,cmp);
		int res=0,sum=0;
		//j是机器,i是任务 
		for(int i=0,j=0;i<m;i++){
			//将所有工作时间大于所需时间的机器找出来 
			while(j<n&&machine[j].first>=task[i].first){
				//记录机器能够解决的对应难度 
				cnt[machine[j].second]++;
				j++;
			}
			//任务难度上限100 
			for(int k=task[i].second;k<=100;k++){
				//遍历所有任务难度,找任务难度对应最低的那个机器
				//如果不存在,由于是按照完成时间顺序排的,其价值更大
				//此时找能完成的机器,即难度对应大于他的
				if(cnt[k]){
					cnt[k]--;
					res++;
					sum+=500*task[i].first+2*task[i].second;
					break;
				} 
			}
		}
		cout<<res<<' '<<sum<<endl;
	}
	AC pleaseqwq;
}

是否存在难度权重更大呢?

答,不存在。因为假设任务时间不一样,那么每多一份任务时间,上升500的价值。而难度顶天也就100。所以难度权重一定小于时间。

最后一次实验过几天发吧,半年多没刷算法题了,头疼,写的时候速度大不如前。。。。。我是fw

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值