第九天 杭电OJ 1087、1203、1003

如果你是和我一样的菜鸟,不知道什么是动态规划,做这类题型建议提前仔细学习动态规划,其中典型的就是背包问题

1087:寻找最大得分的跳法

思路:分别以第1到n个点作为结束的点分析情况,其中第 i 个点的情况建立在第 i-1 个点的基础之上,以此类推,找边界情况

#include<iostream>
#include<algorithm>
using namespace std;

int main(){
	int n;
	while(cin>>n){
		if(n==0)break;
		int *a=new int [n+5];
		int *p=new int [n+5];
		for(int i=0;i<n;i++)
		cin>>a[i];
		p[0]=a[0];
		for(int i=1;i<n;i++)
		{
			p[i]=a[i];
			for(int j=0;j<i;j++)
			if(a[j]<a[i])
			p[i]=max(p[i],p[j]+a[i]);
		}
	cout<<*max_element(p,p+n)<<endl;
	delete a;delete p;
}
return 0;
}

1203: I need offer

(代码中有部分解释,如仍未理解可前往https://blog.csdn.net/weixin_54344261/article/details/118992488阅读详细的分析解读)

#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std;

#define min(a,b) a<b?a:b

struct school{
	int ai;
	double bi;
};
int main(){
	int n,m;
	while(cin>>n>>m){
		if(n==0&&m==0)break;
		school *a=new school [m];//m个学校,每个学校有两个性质,申请费和通过率
		double *p=new double [n+1];//用于存储各个剩余费用的失败率
		for(int i=0;i<=n;i++)开始还没有选,则1到n之间每个费用的申请失败率初始化为1
		p[i]=1.0;
		int ai;
		double bi;
		for(int i=0;i<m;i++){
			cin>>ai>>bi;
			a[i].ai=ai;
			a[i].bi=1.0-bi;//将输入的通过率改为失败率,后续求每个剩余费用的最小失败率即可
		}

        //重点!!!(口述不太好描述,可以自行一步步取值算结果,找规律)
		for(int i=0;i<m;i++)
		for(int j=n;j>=a[i].ai;j--)
// j>=a[j].ai 的作用相当于把 选和不选 进行了分区。每一次的选择相当于在前一个的基础上再进行分区,费用1到n之间也就有了多个区域,每个区域所代表的选与不选的意义也就不一样,也就是不同的选择方法。
		p[j]=min(p[j],p[j-a[i].ai]*a[i].bi);

		p[n]=1.0-p[n];//因为p[n]存的是最小失败率
		p[n]=p[n]*100;
		cout<<fixed<<setprecision(1)<<p[n]<<"%"<<endl;
	}
}

1003:这里需要将输入的数据与处理同时进行,也就是输入一个数据就处理一次,否则存数组容易造成超时。

#include<iostream>
using namespace std;

int main(){
	int n,m;
	cin>>n;
	int t=1;
	while(t<=n){cin>>m;
		int a;
		int sum=0,begin=0,end=0;
        int tempbegin=1;//临时子序列首元素
		int max_sum=-1001; //这里最大和的赋初值为-1001 的作用就是能够确保将输入的第一个任何大小的数(在[-1000,1000]之间的数)都能够执行下叙的第一个if语句。
		for(int i=1;i<=m;i++){
			cin>>a;
			sum+=a;
			if(sum>max_sum){
				max_sum=sum;
				end=i;
				begin=tempbegin;
			}
			if(sum<0){
				tempbegin=i+1;
				sum=0;
			}
		}
		cout<<"Case "<<t<<":"<<endl<<max_sum<<" "<<begin<<" "<<end<<endl;
		if(t<n)cout<<endl;
		t++;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值