C. Knapsack(贪心)

题目传送门

C. Knapsack

题目大意

给你n件物品和一个容量为w的背包,每件物品只能装入一次
求将背包装到 w / 2 − w w/2-w w/2w的一种方案,输出物品数量和装入物品的序号

思路

1、考虑标记是否有存在 w / 2 − w w/2-w w/2w的物品,有就可直接输出
2、考虑是否全部的值加起来都小于 w / 2 w/2 w/2
3、考虑是否全部的值都大于 w w w
前三种情况排除后,贪心:讲物品非递减排序,然后从最小的开始依次装入背包,当装入的东西大于 w / 2 w/2 w/2时即可输出响应的序列

AC Code

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<math.h>
using namespace std;
#define endl '\n'
#define INF 0x3f3f3f3f
#define int long long
#define debug(a) cout<<#a<<"="<<a<<endl;
typedef long long ll;
const double PI=acos(-1.0);
const double e=exp(1.0);
const int M=1e9+7;
const int N=2e5+7;
inline int mymax(int x,int y){return x>y?x:y;}
inline int mymin(int x,int y){return x<y?x:y;}
struct node
{
	int da, id;
}a[N];
int n, w;
int sum, flag, idx, l, r;

bool cmp(node a, node b){
	return a.da<b.da;
}

void solve(){
	cin>>n>>w;
	l=(w+1)/2; r=w;
	sum=flag=0; idx=-1;
	for(int i=1; i<=n; i++){
		cin>>a[i].da; a[i].id=i;
		if(a[i].da>=l && a[i].da<=r) flag=1, idx=i;
		if(a[i].da<l) sum+=a[i].da;
	}
	if(flag) {cout<<1<<endl<<idx<<endl; return ;}
	if(sum<l || sum==0 ) {cout<<"-1"<<endl; return;}

	sort(a+1,a+1+n,cmp);
	sum=0;
	for(int i=1; i<=n; i++){
		sum+=a[i].da;
		if(sum>=l && sum<=r){
			cout<<i<<endl;
			for(int j=1; j<=i; j++){
				cout<<a[j].id<<" ";
			}
			cout<<endl;
			return ;
		}
	}
	return ;
}
signed main(){
	int T;
	cin>>T;
	while(T--) solve();
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值