复习题目(1)

NO.1 飞机降落

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

struct Plane{
	int start, standing, landing;
};
int n;
Plane *plane;
bool *st;

string dfs(int x, int time)
{
	if(x > n) return "YES";
	for(int i = 1; i <= n; i++){
		if(st[i]) continue;//如果当前位置已经考虑就跳过
		if(time > plane[i].start + plane[i].standing) continue;//如果当前飞机最晚可降落时间小于当前时间就直接跳过
		st[i] = true;
		if(dfs(x + 1, max(plane[i].start, time) + plane[i].landing) == "YES") return "YES";
		st[i] = false; 
	}
	return "NO";
}
int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int T; cin >> T;
	while(T--){
		cin >> n;
		plane = new Plane[n + 10];
		st = new bool[n + 10];
		memset(st, false, sizeof(st));
		for(int i = 1; i <= n; i++) cin >> plane[i].start >> plane[i].standing >> plane[i].landing;
		cout << dfs(1, 0) << endl;
	}
	
	return 0;
} 

NO.2 接龙序列

暴力dfs:

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

int n;
int *a;
int ans = -1;

int get_last(int x){
	return x % 10;
}
int get_first(int x){
	while(x > 10) x /= 10;
	return x;
}

void dfs(int x, int last, int cnt)//分别表示当前考虑到了第几个数,当前最后一位数字是什么,当前序列已经有几个数 
{
	if(x > n){
		ans = max(ans, cnt);
		return;
	} 
	if(last == -1) dfs(x + 1, get_last(a[x]), cnt + 1);//如果遇到的是第一个数字,直接记录进去 
	if(last == get_first(a[x])) dfs(x + 1, get_last(a[x]), cnt + 1);//如果当前数字可以记录进去就直接递归
	else dfs(x + 1, last, cnt);//否则不进行记录 
}
int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> n;
	a = new int[n + 10];
	for(int i = 1; i <= n; i++) cin >> a[i];
	
	for(int i = 1; i <= n; i++){
		if(ans > n - i) break;//如果当前答案已经大于剩下未考虑的,直接跳出 
		dfs(i, -1, 0);//从当前位置寻找最长的接龙序列 
	}
	
	cout << n - ans << endl;
	
	return 0; 
}

优化dp:

#include<iostream>
#include<cstring>
#include<algorithm>
#define int long long

using namespace std;

int dp[15] = {0};

signed main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int n; cin >> n;
	for(int i = 1; i <= n; i++){
		string a; cin >> a;
		int first = a[0] - '0', final = a[a.size() - 1] - '0';
		dp[final] = max(dp[first] + 1, dp[final]);
		//在选和不选之间做抉择 
	}
	int ans = 0;
	for(int i = 0; i <= 9; i++) ans = max(ans, dp[i]);
	
	cout << n - ans << endl;
	
	return 0;
} 

NO.3:子串简写

暴力代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#define int long long

using namespace std;

signed main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	
	int ans = 0;
	int k; cin >> k;
	string s; cin >> s;
	char a, b; cin >> a >> b;
	int len = s.size();
	for(int i = 0; i < len - k + 1; i++){
		if(s[i] == a){
			for(int j = i + k - 1; j < len; j++){
				if(s[j] == b) ans++; 
			}
		}
	}
	
	cout << ans << endl;
	
	return 0;
}

记忆化优化:

#include<iostream>
#include<cstring>
#include<algorithm>
#define int long long

using namespace std;

int *mem_a;

signed main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int k; cin >> k;
	string s; cin >> s;
	char a, b; cin >> a >> b;
	int len = s.size();
	mem_a = new int[len + 10];
	memset(mem_a, 0, sizeof(mem_a));
	
	for(int i = 0; i < len - k + 1; i++){
		if(i >= 1) mem_a[i] = mem_a[i - 1];
		if(s[i] == a){
			mem_a[i]++;
		}
	}
	int ans = 0;
	for(int i = k - 1; i < len; i++){
		if(s[i] == b) ans += mem_a[i - k + 1];
	}
	
	cout << ans << endl;
		
	return 0; 
}

NO.4:买瓜

dfs + 剪枝优化

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

int n, m;
int *a;
int *sum;
int ans = 0x3f3f3f3f;
bool flag = 0;

void dfs(int x, double wei, int cnt)
{
	if(wei == (double)m){
		ans = min(ans, cnt);
		return;//如果当前重量符合要求,记录当前答案 
	}
	if(cnt >= ans) return;//如果当前的刀数已经大于合法方案的刀数直接返回  
	if(sum[x] + wei < m) return;//因为所有瓜的重量都是从大到小选,因此当后面的西瓜所有重量都小于剩下要选的重量时候,直接剪枝返回即可
	if(wei > (double)m) return;//如果当前买的瓜重量大于需要的重量,直接返回
	if(x > n) return;//如果当前瓜都考虑完,直接返回 
	
	//选整个瓜
	dfs(x + 1, wei + a[x], cnt);
	
	//选半个瓜
	dfs(x + 1, wei + a[x] / 2.0, cnt + 1);
	
	//不选
	dfs(x + 1, wei, cnt); 
}

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	
	cin >> n >> m;
	a = new int[n + 10];
	sum = new int[n + 10];
	for(int i = 1; i <= n; i++) cin >> a[i];
	
	sort(a + 1, a + n + 1);
	sum[n] = a[n];
	for(int i = n - 1; i >= 1; i--) sum[i] = sum[i + 1] + a[i];
	
	dfs(1, 0, 0);
	if(ans == 0x3f3f3f3f){
		cout << -1 << endl;
		return 0;
	}
	cout << ans << endl;
	
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值