列表

详情


NC51022. 送礼物

描述

作为惩罚,GY被遣送去帮助某神牛给女生送礼物(GY:貌似是个好差事)但是在GY看到礼物之后,他就不这么认为了。某神牛有N个礼物,且异常沉重,但是GY的力气也异常的大(-_-b),他一次可以搬动重量和在w以下的任意多个物品。GY希望一次搬掉尽量重的一些物品,请你告诉他在他的力气范围内一次性能搬动的最大重量是多少。

输入描述

第一行两个整数,分别代表W和N。
以后N行,每行一个正整数表示G[i],

输出描述

仅一个整数,表示GY在他的力气范围内一次性能搬动的最大重量。

示例1

输入:

20 5
7
5
4
18
1

输出:

19

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 1409ms, 内存消耗: 66040K, 提交时间: 2020-07-20 16:20:43

#include <bits/stdc++.h>

using namespace std;
const int maxn=(1<<24)+10;
int a[50],ret[maxn],upper,cnt1=0,cnt2=0,w;
void dfs(int pos,int cnt)
{
    if(pos>upper) return;
    if((long long)ret[cnt]+a[pos]<=w){
        ret[++cnt2]=ret[cnt]+a[pos];
        dfs(pos+1,cnt2);
    }
    dfs(pos+1,cnt);
}
int main()
{
    int n,ans=0;
    cin>>w>>n;
    for(int i=1;i<=n;i++)  cin>>a[i];
    sort(a+1,a+n+1,greater<int>());
    upper=n/2;dfs(1,0);
    cnt1=cnt2;
    upper=n;dfs(n/2+1,0);
    sort(ret+1,ret+cnt1+1);
    sort(ret+cnt1+1,ret+cnt2+1,greater<int>());
    for(int i=1;i<=cnt1;i++){
    ans=max(ans,ret[i]+*lower_bound(ret+cnt1+1,ret+cnt2+1,w-ret[i],greater<int>()));
    if(ans==w) break;
    }
    cout<<ans;
    return 0;
}

Python3 解法, 执行用时: 3529ms, 内存消耗: 187820K, 提交时间: 2021-08-17 02:28:07

from bisect import bisect_right

W, N = map(int, input().split())
left = set([0])
for i in range(N//2):
    e = int(input())
    for s in list(left):
        tmp = s + e
        if tmp not in left and tmp <= W:
            left.add(tmp)

right = set([0])
for i in range(N - N//2):
    e = int(input())
    for s in list(right):
        tmp = s + e
        if tmp not in right and tmp <= W:
            right.add(tmp)            
right = sorted(right)

ans = 0
for a in left:
    tmp = W - a
    idx = bisect_right(right, tmp) - 1
    if idx >= 0:
        b = right[idx]
        ans = max(ans, a + b)
print(ans)

C++ 解法, 执行用时: 954ms, 内存消耗: 38516K, 提交时间: 2021-10-16 13:56:17

#include<bits/stdc++.h>
using namespace std;
int  n,w,k,cnt=1,ans;
int a[1<<25],g[50];
void dfs1(int v,int sum)
{
	if(v==k)
	{
		a[cnt++]=sum;
		return;
	}
	dfs1(v+1,sum);
	if((long long)sum+g[v]<=w)
	dfs1(v+1,sum+g[v]);
}
void dfs2(int v,int sum)
{
	if(v==n)
	{
		int pos=upper_bound(a,a+cnt,w-sum)-a-1;
		ans=max(ans,a[pos]+sum);
		return; 
	}
	dfs2(v+1,sum);
	if((long long)sum+g[v]<=w)
	dfs2(v+1,sum+g[v]);
}
int main()
{
	cin>>w>>n;
	for(int i=0;i<n;i++)
	cin>>g[i];
	sort(g,g+n,greater<int>());
	k=n/2+2;
	dfs1(0,0);
	sort(a,a+cnt);
	cnt=unique(a,a+cnt)-a;
	dfs2(k,0);
	cout<<ans<<endl;
	return 0;
}

上一题