HENAU

目录

B - 删数问题

输入格式

输出格式

C - 股票买卖

D - 数列分段


B - 删数问题

键盘输入一个高精度的正整数 nn,去掉其中任意 kk 个数字后剩下的数字按原左右次序将组成一个新的正整数。编程对给定的 n,kn,k,寻找一种方案使得剩下的数字组成的新数最小。

输出应包括所去掉的数字的位置和组成的新的整数。

输入格式

第一行一个高精度整数 nn,nn 不超过 200200 位。

第二行一个整数 kk,kk 小于 nn 的位数,表示要删去的数字个数。

输出格式

一个合法的整数,表示最后剩下的最小数。

Sample 1

InputcopyOutputcopy
175438 
4
13

Sample 2

InputcopyOutputcopy
101 2
0

思路:我们每次只需要删除第一个开始下降的数即可,如果所有位数上的数都是单调递增,那么就删除最后一位数即可。

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner cin=new Scanner(System.in);
		String s=cin.next();
		int k=cin.nextInt();
		StringBuffer sb=new StringBuffer(s);
		while(k-->0) {
			int x=-1;
			for(int i=0;i<sb.length()-1;i++) {
				if(sb.charAt(i)>sb.charAt(i+1)) {
					x=i;
					sb.deleteCharAt(i);
					break;
				}
			}
			if(x==-1)sb.deleteCharAt(sb.length()-1);
//			System.out.println(sb.length());
		}
//		System.out.println(sb.toString());
		String ss=sb.toString().replaceAll("^0*", "");
		if(ss.length()==0)System.out.println(0);
		else {
			System.out.println(ss);
		}
		
	}

}

C - 股票买卖

最近越来越多的人都投身股市,阿福也有点心动了。谨记着“股市有风险,入市需谨慎”,阿福决定先来研究一下简化版的股票买卖问题。

假设阿福已经准确预测出了某只股票在未来 N 天的价格,他希望买卖两次,使得获得的利润最高。为了计算简单起见,利润的计算方式为卖出的价格减去买入的价格。

同一天可以进行多次买卖。但是在第一次买入之后,必须要先卖出,然后才可以第二次买入。

现在,阿福想知道他最多可以获得多少利润。

Input

输入的第一行是一个整数 T (T <= 50) ,表示一共有 T 组数据。
接下来的每组数据,第一行是一个整数 N (1 <= N <= 100, 000) ,表示一共有 N 天。第二行是 N 个被空格分开的整数,表示每天该股票的价格。该股票每天的价格的绝对值均不会超过 1,000,000 。

Output

对于每组数据,输出一行。该行包含一个整数,表示阿福能够获得的最大的利润。

Sample

InputcopyOutputcopy
3
7
5 14 -2 4 9 3 17
6
6 8 7 4 1 -2
4
18 9 5 2
28
2
0

Hint

对于第一组样例,阿福可以第 1 次在第 1 天买入(价格为 5 ),然后在第 2 天卖出(价格为 14 )。第 2 次在第 3 天买入(价格为 -2 ),然后在第 7 天卖出(价格为 17 )。一共获得的利润是 (14 - 5) + (17 - (-2)) = 28
对于第二组样例,阿福可以第 1 次在第 1 天买入(价格为 6 ),然后在第 2 天卖出(价格为 8 )。第 2 次仍然在第 2 天买入,然后在第 2 天卖出。一共获得的利润是 8 - 6 = 2
对于第三组样例,由于价格一直在下跌,阿福可以随便选择一天买入之后迅速卖出。获得的最大利润为 0

思路:根据题意可知,我们需要在n天内找到两次买入售出的最大利润,并且在第一次出售之后才能进行第二次的操作,那么我们便可以从两端开始向中间聚拢, 然后我们便可以使用动态规划进行动态的处理,最后遍历求得f[i]+g[i]的最大值即可

#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int f[N]; //动态表示在第i天之前购买并出售的最大利润 
int g[N];//动态表示在第i-n天内购买并出售的最大值利润 
int a[N];

int main(){
	int t,n;
	scanf("%d",&t);
	
	while(t--){
		//一定要初始化数组,防止上一数据对本数据造成干扰 
		memset(f,-1,sizeof(f));
		memset(g,-1,sizeof(g));
		
		scanf("%d",&n);
		for(int i=1;i<=n;i++)scanf("%d",&a[i]);
		
		int ma=-1e9,mi=1e9;
		
		for(int i=1;i<=n;i++){
			mi=min(mi,a[i]);
			f[i]=max(f[i-1],a[i]-mi);
		}
		
		for(int i=n;i>0;i--){
			ma=max(ma,a[i]);
			g[i]=max(g[i+1],ma-a[i]);
		}
		
		int maxn=0;
		for(int i=1;i<=n;i++){
			maxn=max(maxn,f[i]+g[i]);
		}
		
		printf("%d\n",maxn);
	}
	return 0;
}
import java.io.*;
import java.util.*;

public class Main {

//快输模板
	static class FastScanner{//用于快速读入大量数据
		BufferedReader br;
		StringTokenizer st;
		public FastScanner(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in),16384);
			eat("");
		}
		public void eat(String s) {
			st = new StringTokenizer(s);
		}
		public String nextLine() {
			try {
				return br.readLine();
			} catch (IOException e) {
				return null;
			}
		}
		public boolean hasNext() {
			while(!st.hasMoreTokens()) {
				String s = nextLine();
				if(s==null) return false;
				eat(s);
			}
			return true;
		}
		public String next() {
			hasNext();
			return st.nextToken();
		}
		public int nextInt() {
			return Integer.parseInt(next());
		}
		public long nextLong() {
			return Long.parseLong(next());
		}
	}
	static FastScanner cin = new FastScanner(System.in);//快读
	static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
//核心代码
	static int N=100010;
	static int f[]=new int[N+1];//动态表示在第i天之前购买并出售的最大利润
	static int g[]=new int[N+1];//动态表示在第i-n天内购买并出售的最大值利润 
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int t=cin.nextInt();
		
		while(t-->0) {
			int n=cin.nextInt();
			int a[]=new int[n+1];
			
			//一定要初始化数组,防止上一数据对本数据造成干扰
			Arrays.fill(f,0);
			Arrays.fill(g,0);
			
			for(int i=1;i<=n;i++)a[i]=cin.nextInt();
			
			int min=Integer.MAX_VALUE,max=Integer.MIN_VALUE;
			for(int i=1;i<=n;i++) {
				min=Math.min(min,a[i]);
				f[i]=Math.max(a[i]-min, f[i-1]);
			}
			max=a[n];
			for(int i=n-1;i>0;i--) {
				max=Math.max(max, a[i]);
				g[i]=Math.max(g[i+1],max-a[i]);
			}
			
			int ans=0;
			for(int i=1;i<=n;i++) {
				ans=Math.max(ans, f[i]+g[i]);
			}
			
			out.println(ans);
			out.flush();
		}
		
	}

}

D - 数列分段

题目描述

对于给定的一个长度为 NN 的正整数数列 Ai​,现要将其分成连续的若干段,并且每段和不超过 M(可以等于 M),问最少能将其分成多少段使得满足要求。

输入格式

第一行包含两个正整数 N,M,表示了数列 A_iAi​ 的长度与每段和的最大值;

第二行包含 N 个空格隔开的非负整数 A_iAi​。

输出格式

输出文件仅包含一个正整数,输出最少划分的段数。

样例

InputcopyOutputcopy
5 6
4 2 4 5 1
3

数据范围与提示

对于 20\%20% 的数据,有N\le 10N≤10;

对于 40\%40% 的数据,有N\le 1000N≤1000;

对于 100\%100% 的数据,有 N\le 10^5, M\le 10^9N≤105,M≤109,MM 大于所有数的最大值。

import java.util.Scanner;

public class Main{

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner cin=new Scanner(System.in);
		int n=cin.nextInt();
		int m=cin.nextInt();
		int cnt=1,sum=0;
		
		for(int i=0;i<n;i++) {
			int x=cin.nextInt();
			sum+=x;
			if(sum>m) {
				sum=x;cnt++;
			}
		}
		
		System.out.println(cnt);
	}

}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值