原题链接: http://codeforces.com/contest/1447/problem/C
测试样例
input
3
1 3
3
6 2
19 8 19 69 9 4
7 12
1 1 1 17 1 1 1
output
1
1
-1
6
1 2 3 5 6 7
Note
In the first test case, you can take the item of weight 3 and fill the knapsack just right.
In the second test case, all the items are larger than the knapsack’s capacity. Therefore, the answer is −1.
In the third test case, you fill the knapsack exactly in half.
题意: 你有一个容量的包,这里现在有
个
重的东西,你需要选择这些东西装入包中,要使得装入的包中的重量
满足
,输出任意方案,如果没有则输出
。
解题思路: 我们很容易知道,单个个体因为大于包容量的可以剔除,单个个体满足的可以直接装入得到答案,而单个个体是小于的我们则可以累加满足得到,如果累加也不满足,则说明没有解决方案。 有了这个思想,我们则可以解决此题,即开一个数组存储标号并利用该数组从大到小排序按权重来排。这个时候遍历数组,利用flag判断是否可以解决。同时将解决方案放入数组
中。
AC代码
/*
*
*
*/
//POJ不支持
using namespace std;
const int inf=0x3f3f3f3f;//无穷大。
const int maxn=2e5+5;//限定值。
typedef long long ll;
ll t,n,m;
ll W;
ll w[maxn];
int pos[maxn];
bool cmp(int i,int j){
return w[i]>w[j];
}
int main(){
while(cin>>t){
while(t--){
cin>>n>>W;
rep(i,1,n){
cin>>w[i];
pos[i]=i;
}
sort(pos+1,pos+1+n,cmp);
bool flag=false;
vector<int> result;
ll sum=0;
rep(i,1,n){
if(w[pos[i]]>W)continue;
if(w[pos[i]]*2>=W){
flag=true;
result.push_back(pos[i]);
break;
}
else{
sum+=w[pos[i]];
result.push_back(pos[i]);
if(sum*2>=W&&sum<=W){
flag=true;
break;
}
}
}
if(!flag){
cout<<-1<<endl;
}
else{
cout<<result.size()<<endl;
rep(i,0,result.size()-1){
cout<<result[i]<<" ";
}
cout<<endl;
}
}
}
return 0;
}```