阿里春招笔试2020.3.20(暴搜/dp)

申明:大概题意是从牛客网讨论区嫖的,题目的输入、输出以及数据数据范围也有些不知,大家看看思路就好,这些细节就不管了QAQ。有错欢迎纠正~
阿里笔试3.20

题目一(暴搜)

扑克牌1-10,各4张,共40张。随便抽一些,一个10个数字的数组 1 1 1 2 2 2 2 2 1 1 ,表示每个牌的数目,可以五张顺子,可以三个对组成连队,可以一个对,可以单张,问最少多少次可以出完牌。
思路:暴搜

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 510;

int a[12];
int ans;
void dfs(int cur) {
	if(cur >= ans) return;
	bool flag = 0;
	for(int i = 1;i <= 10;++i)
		if(a[i]) {
			flag = 1;break;
		}
	if(!flag) {
		ans = cur;return;
	}
	for(int i = 1;i <= 6;++i) {//顺子 
		if(a[i]&&a[i+1]&&a[i+2]&&a[i+3]&&a[i+4]) {
			for(int j = i;j <= i+4;++j)
				a[j]--;
			dfs(cur+1);
			for(int j = i;j <= i+4;++j)
				a[j]++;
		}
	}
	for(int i = 1;i <= 8;++i) {//连对 
		if(a[i]>1&&a[i+1]>1&&a[i+2]>1) {
			for(int j = i;j <= i+2;++j)
				a[j] -= 2;
			dfs(cur+1);
			for(int j = i;j <= i+2;++j)
				a[j] += 2;
		}
	}
	for(int i = 1;i <= 10;++i)
		cur += (a[i]+1)/2; 
	if(ans > cur) ans = cur;
}
int main() {
	for(int i = 1;i <= 10;++i) {
		scanf("%d",&a[i]);
	}
	ans = 40;
	dfs(0);
	printf("%d\n",ans);
} 
/*
1 1 1 2 2 2 2 2 1 1
 
*/

题目二(dp)

一堆各自非递减的字串,能组成的最长非递减字串的长度。字符串由小写字母组成。
思路:dp,用 d p i dp_i 表示以字符 a + i 'a'+i 结尾的最长字符串,需要先排序。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 100010;


int n;
int dp[27];
char str[maxn];
struct node {
	int s,e;
	int len;
	bool operator <(const node &b) {
		if(e == b.e)  return s<b.s;
		return e<b.e;
	}
}a[maxn];

int main() {
	scanf("%d",&n);
	for(int i = 0;i < n;++i) {
		scanf("%s",str);
		a[i].s = str[0]-'a';
		a[i].len = strlen(str);
		a[i].e = str[a[i].len-1]-'a';
	}
	sort(a,a+n);
	for(int i = 0;i < n;++i) {
		int res = dp[a[i].e];
		for(int j = 0;j <= a[i].s;++j) {
			res = max(res,dp[j]+a[i].len);
		}
		dp[a[i].e] = res;
	}
	int ans = 0;
	for(int i = 0;i < 26;++i) {
		ans = max(ans,dp[i]);
	}
	printf("%d\n",ans);
}
/*
4
aaa
bcd
bcdef
zzz
*/
发布了152 篇原创文章 · 获赞 2 · 访问量 6444

猜你喜欢

转载自blog.csdn.net/weixin_43918473/article/details/105223593
今日推荐