首页 > 阿里7.27笔试思路
头像
林不厌
编辑于 2020-07-28 10:28
+ 关注

阿里7.27笔试思路

两道题都是结束以后才想出来。。。两题都只过了20%,哭了。
第一题应该是只有当所有数字都出现偶数次时候第二个人才能赢,其他情况都是第一个人赢。
第二题我以为是只能取每一层的一头一尾两个,写了一个dp,只过了20%,结束以后我发现数据给的n和c最大为100,m最大为10000,说明如果m >= n * c,所有物品都可以拿走,所以每一层如果已经拿了第1个和第c个,那就还可以继续拿第2个和第c-1个。
个人觉得是个背包dp,然后时间不够呀!!!
好气!结束了才想到。

(代码有问题。。。不好意思,我删掉重写)

昨晚躺在床上突然发现之前这样子贪心找到的并不是最优解,思来想去,发现可以用滑动窗口预处理出当前层取x个物品可以获得的最大价值存在数组中,然后dp,复杂度O(n*(c^2+m*c)),我觉得应该没有问题,欢迎大家指正!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int a[110], val[110];
int dp[10010];
int main()
{
	int n, m, c;
	cin >> n >> m;
	memset(dp, 0, sizeof dp);
	for (int i = 0; i < n; i++){
		int sum = 0;//求当前层物品价值和
		cin >> c;
		for (int j = 0; j < c; j++){
			cin >> a[j];
			sum += a[j];
		}
		memset(val, 0, sizeof val);
		for (int k = 1; k <= c; k++){ // 当前层获得k件物品可得的最大值存入val
			int index = 0, now = 0;//滑动窗口,窗口大小为c-k
			while (index < c-k){
				now += a[index];
				index++;
			}
			val[k] = max(val[k], sum-now);
			while (index < c){
				now += a[index];
				now -= a[index-c+k];
				val[k] = max(val[k], sum-now);
				index++;
			}
		}
		for (int j = m; j > 0; j--)
			for (int k = 1; k <= min(j, c); k++)
				dp[j] = max(dp[j], dp[j-k]+val[k]);
	}
	cout << dp[m] << endl;
	return 0;
}


全部评论

(17) 回帖
加载中...
话题 回帖

相关热帖

近期热帖

历年真题 真题热练榜 24小时
技术(软件)/信息技术类
查看全部

近期精华帖

热门推荐