贪心(一本通)

均分纸牌

#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int n,a[101];
 


int main(){
	cin>>n;
	int ave=0,step=0;
	for(int i=1;i<=n;i++) {
		cin>>a[i];
		ave+=a[i];
	}
	ave/=n;
	for(int i=1;i<=n;i++) a[i]-=ave;
	int s=1,e=n;
	while(s<=n&&a[s]==0) s++;  //清除开始和结尾的0 
	while(e>=1&&a[e]==0) e--;
	while(s<e){
		a[s+1]+=a[s];
		a[s]=0;
		step++;
		s++;
		while(a[s]==0&&s<e) s++; //防止中间有0 
	}
	cout<<step<<endl;
return 0;
}

删数问题

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
using namespace std;
int n,s;
char a[241];
//删数问题:寻找递减区间首字母删除 

int main(){
	cin>>a;
	n=strlen(a);
	cin>>s;
	while(s--){
		for(int i=0;i<n-1;i++){ //这里是n-1!!!! ,不然i+1会越界 
		if(a[i]>a[i+1]) {
			for(int j=i;j<n-1;j++) a[j]=a[j+1];//替换 
			break; //!!!!!!!!!!!!!这里必须有,因为一次只能删一个 
		}
		n--;//已经去掉一个了所以要剪掉 
	}
	}
	bool flag=0;
	for(int i=0;i<n;i++){
		if(a[i]!='0') flag=1;
		if(flag) cout<<a[i];  //要去掉开头的0,但是又不能去掉中间的0 
	} 
	cout<<endl;
return 0;
}

拦截导弹

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
using namespace std;
int a[1001],b[1001];//导弹和能拦截的高度
 


int main(){
	int i=1;
	while(scanf("%d",&a[i++])!=EOF);
	int k=1;b[k]=a[1];
	for(int j=2;j<=i;j++){
		int f=0;
		for(int l=1;l<=k;l++){
			if(b[l]>=a[j]) {
				if(f==0) f=l;
				else if(b[l]<b[f]) f=l;//这里是贪心策略,选择在能拦截的系统里面高度最小的 
			}
			
		}
		if(f==0) {
				k++;b[k]=a[j];
			} 
			else b[f]=a[j];
	}
	cout<<k<<endl;
return 0;
}

活动选择

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
using namespace std;
int n;
struct acti{
	int st;
	int ed;
}hei[1001];
bool cmp(acti a,acti b){
	return a.ed<b.ed;
}

int main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>hei[i].st>>hei[i].ed;
	sort(hei+1,hei+n+1,cmp);
	int sum=0;
	int temp=-11111;
	for(int i=1;i<=n;i++){
		if(hei[i].st>=temp) {   //为什么从1开始:并设置temp初始值那么小:为了使第一个也能一样去计算 
			sum++;
		temp=hei[i].ed;//还有这里是能够保证这个活动算进去后temp才能改变 
		}              //因为这个不行,下一个说不定行,但是如果每循环一次就改变temp那么下一个就永远不行!!!!!!!注意位置 
		
	}
	cout<<sum<<endl;
return 0;
}

最大子矩阵

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
using namespace std;
int map[101][101];
int sum[101][101];
int ans[101][101];
int main(){
	int n;
	cin>>n;
	int max=-1111;
	/*
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++) cin>>map[i][j];
	memset(sum,0,sizeof(sum));
	memset(ans,0,sizeof(ans));
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++) sum[i][j]+=map[i][j];
	for(int i=n;i>=1;i--){
		for(int j=n;j>=1;j--){
			for(int k=1;k<i;k++){
				for(int m=1;m<j;m++){
					ans[i][j]=sum[i][j]-sum[k-1][j]-sum[i][m-1]+sum[k-1][m-1]; 
					if(ans[i][j]>max) max=ans[i][j];
				}
			}
		}
	}
	cout<<max-1<<endl; */ //额。。。。。我不知道为什么错了哭哭
	 for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++) {
		cin>>map[i][j];
		map[i][j]+=map[i][j-1]; //到i与j这里的总和 
	}
	int ans=0;
	for(int i=0;i<=n-1;i++){//这里的下标必须为0和i-1因为可能只有一列!所有记得,不然会错 
		for(int j=i+1;j<=n;j++){
			ans=0;//这里要清零!!!!!!!!注意 
			for(int k=1;k<=n;k++){
			ans+=map[k][j]-map[k][i];	//还有这里是+= 
			if(max<ans) max=ans; 
			if(ans<0) ans=0;     //这一句也得记住啊!! 
			}
		}
	} 
	cout<<max<<endl; 
	 
return 0;
}

crossing the river

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
using namespace std;
int t;
int n;
int a[1001];

int main(){
	cin>>t;
	while(t--){
		cin>>n;
		int sum=0;
		for(int i=0;i<n;i++) cin>>a[i];
		sort(a,a+n);
		int i; 
		if(n==1) sum=a[1];
		else if(n==2) sum=a[1]+a[2];
		else{
			for( i=n-1;i>2;i-=2){
				if(a[0]+a[0]+a[i]+a[i-1]<a[1]+a[0]+a[i]+a[1])
				sum+=a[0]+a[0]+a[i]+a[i-1];//两种情况 
				else sum+=a[1]+a[0]+a[i]+a[1]; 
			}
		}
		if(i==2) sum+=a[0]+a[1]+a[2];//还有后面的处理!!!! 
		else if(i==1) sum+=a[1];
		else sum+=a[0];
		cout<<sum<<endl;
	}
return 0;
}

参考:https://blog.csdn.net/mengdicfm/article/details/95333168

排队接水

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
using namespace std;
int w[10001];
int a[1001];
int n; 
int main(){
	int num=-999999,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>w[i];
	int minx=99999,minj=0;
	for(int i=1;i<=m;i++){
		 a[i]=w[i];
		 if(w[i]<minx) {
		 	minx=w[i];
		 	minj=i;
		 }
	}
	for(int i=m+1;i<=n;i++){
		a[minj]+=w[i];
		minx=888888;
		for(int j=1;j<=m;j++){
			if(a[j]<minx){
				minx=a[j];minj=j;
			}
		}
	}
	for(int i=1;i<=m;i++) num=max(num,a[i]);
	cout<<num<<endl;
return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值