zoukankan      html  css  js  c++  java
  • 【GOJ 3015】疯狂外星人

    题目

    正解

    要使得包正好充满,无法再放入其他的物品,我们不妨考虑枚举正好塞不下的物品是哪一件,即
    剩下不拿的物品里面最小的物品是哪一件。

    可以发现,因为正好放不进去的物品满足是不拿的物品里面最小的物品,所以比这个物品小的,肯定全部要塞下去,然后剩下比他大的物品,显然就是我们经典的(0/1)背包的做法。

    有个坑点是,所有的物品都放下了,背包还是没有溢出,按照题意,这算是一种方案

    代码

    #include<bits/stdc++.h>
    using namespace std;
    using LL=long long;
    LL f[100005],a[5005];
    int main() {
    	LL T;
    	scanf("%lld",&T);
    	while(T--) {
    		LL sum=0;
    		memset(f,0,sizeof(f)),f[0]=1;
    		LL n,m;
    		scanf("%lld %lld",&n,&m);
    		for(LL i=1; i<=n; i++) {
    			scanf("%lld",a+i),sum+=a[i];
    		}
    		if(sum<=m) {
    			printf("1
    ");
    			continue;
    		}
    		sort(a+1,a+1+n);
    		LL ans=0;
    		for(LL i=n; i; i--) {
    			int k=sum-a[i]-m;
    			k=max(k,0);
    			for(int j=k; j<sum-m; j++) {//每局第一个装不下的酒
    				ans+=f[j];
    			}//比这个物品小的,肯定全部要塞下去(区间对应
    			for(int j=sum; j>=a[i]; j--) {
    				f[j]+=f[j-a[i]];
    			}//比它大的,可以加上它的酒量。
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    画了朵花
    定位
    浮动
    盒模型
    html+css笔记1
    闭包
    高阶函数
    函数
    Map Set iterable
    git stash clear/drop 后代码如何恢复
  • 原文地址:https://www.cnblogs.com/Sam2007/p/13398450.html
Copyright © 2011-2022 走看看