阿里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;
}


#阿里巴巴#
全部评论
public static void main(String[] args){     int n,m,c;     n=sc.nextInt();     m=sc.nextInt();     for(int i=0 ; i<n ; i++ ){         int sum=0;// 求该层的物品价值总和         c=sc.nextInt();         for(int j=0 ; j<c ; j++ ){             a[j] = sc.nextInt();             sum+=a[j];         }         Arrays.fill(val,0);         for(int k=1 ; k<=c ; k++){ // 当前层获得k件物品可得的最大值存入val             int index= 0 , now = 0;// 滑动窗口,窗口大小为c-k             while(index < c-k)// 初始窗口 从第一个开始累加                 now +=a[index++];             val[k] = Math.max(val[k],sum-now);             while(index<c){ // 开始往右边移动                 now+= a[index];                 now-=a[index-(c-k)];                 val[k] = Math.max(val[k],sum-now); //求的是窗口以外的数和最大值                 index++;             }         }         // 此时该层的val已经求出 01背包求解         for(int j=m ; j>0 ; j--){             for(int k=1 ; k<= Math.min(j,c) ; j++ )                 dp[j] = Math.max(dp[j],dp[j-k]+val[k]);         }     }       System.out.println(dp[m]); }
1 回复 分享
发布于 2020-07-28 15:23
第一题博弈,直接看最后出现的数字次数是奇数则先手赢,偶数则后手赢; 第二题感觉是dp但是不会= =直接用贪心混20分
1 回复 分享
发布于 2020-07-27 20:42
第二题两端拿掉了,中间暴露出来还可以拿中间的吗!完蛋,题目都没懂
1 回复 分享
发布于 2020-07-27 20:34
感觉就是这个思路,先生成每层的取用数组,然后再从上到下根据取用数组生成dp数组,最后遍历最后一层dp数组获得结果。
点赞 回复 分享
发布于 2020-07-29 12:32
获取val的第k个 能否用双指针指向两边,然后不断往中间移,进行存储呢?感觉这个滑动窗口有点看不懂。。。
点赞 回复 分享
发布于 2020-07-28 14:21
如果先做预处理将每层的取j个的最优情况 放在vector<vector<int>>value;中, value[i][j]代表在第i层取j个的最优解,做出这样的二维数组,时间复杂度是O(100*10000);每一层是O(10000),最多100层, 然后可以用动态规划。 dp[i][j] 表示到第i层,取j个,的最优解,   那么dp[i][j]等于,dp[i-1][j-x]+value[i][x];x是0->j;就是前面用0个,这层用j个,前面用1个这层用j-1个。。。的最优解, 然后时间复杂度是 O(100*100*100),第一个是一共100层,第二个是 j最多取道100个,第三个是从 0-j,1-j-1...j-0;一共比较100次。 所以最后的时间复杂度是O(1百万); 欢迎指正。
点赞 回复 分享
发布于 2020-07-28 13:46
我不知道我理解题意对不对,我想的是弄一个新类记录每个物品所在位置以及价值,我就把所有层头尾两个数放到大根堆PQ(按价值排序)里,完了每次把顶上的值拿出来,按照他的位置去把他后面或者前面新暴露出来的点放进去,一直做M次,这样,请做过的大佬指点一下,谢了。
点赞 回复 分享
发布于 2020-07-28 09:48
Java怎么写第二题的输入啊。。。我用常规Scanner套路 用两层for循环 想第一层写宝箱数量 第二层写宝物价值。 内循环循环完一次直接报错😂 有大佬可以告诉我应该怎么写吗? 我太蔡了
点赞 回复 分享
发布于 2020-07-28 00:44
你单独每一层的dp状态写错了  1 4 6 10 2 2 10 1 5 这样的数据你肯定过不了
点赞 回复 分享
发布于 2020-07-27 23:19
请问有原题吗
点赞 回复 分享
发布于 2020-07-27 21:35
a了1点2🤣,第二题感觉都没读懂题瞎混了20%
点赞 回复 分享
发布于 2020-07-27 20:37
第一题输出,我没明白;T个测试用例,是每个测试用例都cout<<"NIUNIU"或者“NIUMEI”<<endl;(我的思路和楼主一样,但是输入输出没搞定~)😥
点赞 回复 分享
发布于 2020-07-27 20:35
草原来是这样,我也是20%
点赞 回复 分享
发布于 2020-07-27 20:32
求讲第二题思路
点赞 回复 分享
发布于 2020-07-27 20:30
草,第一题这么简单,我就是一个测试样例都过不了,哎
点赞 回复 分享
发布于 2020-07-27 20:30
第一题过了 第二题没写出来 dp不知道怎么设计 感觉复杂度爆表
点赞 回复 分享
发布于 2020-07-27 20:29
我0%
点赞 回复 分享
发布于 2020-07-27 20:29

相关推荐

不愿透露姓名的神秘牛友
06-19 17:02
鼠鼠深知pdd的强度很大,但是现在没有大厂offer,只有一些不知名小厂我是拒绝等秋招呢,还是接下?求大家帮忙判断一下!
水中水之下水道的鼠鼠:接了再说,不图转正的话混个实习经历也不错
投递拼多多集团-PDD等公司10个岗位 >
点赞 评论 收藏
分享
避坑恶心到我了大家好,今天我想跟大家聊聊我在成都千子成智能科技有限公司(以下简称千子成)的求职经历,希望能给大家一些参考。千子成的母公司是“同创主悦”,主要经营各种产品,比如菜刀、POS机、电话卡等等。听起来是不是有点像地推销售公司?没错,就是那种类型的公司。我当时刚毕业,急需一份临时工作,所以在BOSS上看到了千子成的招聘信息。他们承诺无责底薪5000元,还包住宿,这吸引了我。面试的时候,HR也说了同样的话,感觉挺靠谱的。于是,我满怀期待地等待结果。结果出来后,我通过了面试,第二天就收到了试岗通知。试岗的内容就是地推销售,公司划定一个区域,然后你就得见人就问,问店铺、问路人,一直问到他们有意向为止。如果他们有兴趣,你就得摇同事帮忙推动,促进成交。说说一天的工作安排吧。工作时间是从早上8:30到晚上18:30。早上7点有人叫你起床,收拾后去公司,然后唱歌跳舞(销售公司都这样),7:55早课(类似宣誓),8:05同事间联系销售话术,8:15分享销售技巧,8:30经理训话。9:20左右从公司下市场,公交、地铁、自行车自费。到了市场大概10点左右,开始地推工作。中午吃饭时间大约是12:00,公司附近的路边盖饭面馆店自费AA,吃饭时间大约40分钟左右。吃完饭后继续地推工作,没有所谓的固定中午午休时间。下午6点下班后返回公司,不能直接下班,需要与同事交流话术,经理讲话洗脑。正常情况下9点下班。整个上班的一天中,早上到公司就是站着的,到晚上下班前都是站着。每天步数2万步以上。公司员工没有自己的工位,百来号人挤在一个20平方米的空间里听经理洗脑。白天就在市场上奔波,公司的投入成本几乎只有租金和工资,没有中央空调。早上2小时,晚上加班2小时,纯蒸桑拿。没有任何福利,节假日也没有3倍工资之类的。偶尔会有冲的酸梅汤和西瓜什么的。公司的晋升路径也很有意思:新人—组长—领队—主管—副经理—经理。要求是业绩和团队人数,类似传销模式,把人留下来。新人不能加微信、不能吐槽公司、不能有负面情绪、不能谈恋爱、不能说累。在公司没有任何坐的地方,不能依墙而坐。早上吃早饭在公司外面的安全通道,未到上班时间还会让你吃快些不能磨蹭。总之就是想榨干你。复试的时候,带你的师傅会给你营造一个钱多事少离家近的工作氛围,吹嘘工资有多高、还能吹自己毕业于好大学。然后让你早点来公司、无偿加班、抓住你可能不会走的心思进一步压榨你。总之,大家在找工作的时候一定要擦亮眼睛,避免踩坑!———来自网友
qq乃乃好喝到咩噗茶:不要做没有专业门槛的工作
点赞 评论 收藏
分享
屌丝逆袭咸鱼计划:心态摆好,man,晚点找早点找到最后都是为了提升自己好进正职,努力提升自己才是最关键的😤难道说现在找不到找的太晚了就炸了可以鸡鸡了吗😤早实习晚实习不都是为了以后多积累,大四学长有的秋招进的也不妨碍有的春招进,人生就这样
点赞 评论 收藏
分享
评论
点赞
13
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务