问题:30 盾神与砝码称重
问题描述:
有一天,他在宿舍里无意中发现了一个天平!这个天平很奇怪,有n个完好的砝码,但是没有游码。盾神为他的发现兴奋不已!于是他准备去称一称自己的东西。他准备好了m种物品去称。神奇的是,盾神一早就知道这m种物品的重量,他现在是想看看这个天平能不能称出这些物品出来。但是盾神稍微想了1秒钟以后就觉得这个问题太难了,于是就丢给了你。
注意:砝码可以和物品一起放在天平的同一边。
输入说明 :
第一行为两个数,n和m。
第二行为n个数,表示这n个砝码的重量。
第三行为m个数,表示这m个物品的重量。
1<=n<=24, 1<=m<=10.
输出说明 :
输出m行,对于第i行,如果第i个物品能被称出,输出YES否则输出NO。
输入范例 :
4 3
10 7 2 19
6 5 11
输出范例 :
NO
YES
YES
思路:
按常规思路来的,但是又TLE了
已经尽我所能剪枝咯
代码实现:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int *fama,*item;
//砝码是否被用中
bool *isUsing;
bool *res;
//剩余砝码总重量
int twFama=0;
void DFS(int k,int l,int iw,int fw)
{
if(res[l]==true) return;
else if(item[l]+iw==fw)
{
res[l]=true;
return;
}
//物品那边的重量超过砝码那边和剩余砝码总重量之和 或 砝码那边超过物品那边和剩余砝码总重量之和
else if(iw+item[l] > fw+twFama || fw > twFama+iw+item[l]) return;
else if(k==n-1) return;
for(int i=0;i<n;i++)
{
if(isUsing[i])
continue;
isUsing[i]=true;
twFama-=fama[i];
iw+=fama[i];
DFS(i+1,l,iw,fw);
iw-=fama[i];
fw+=fama[i];
DFS(i+1,l,iw,fw);
fw-=fama[i];
twFama+=fama[i];
isUsing[i]=false;
}
}
int main()
{
cin>>n>>m;
item=new int[m];
fama=new int[n];
isUsing=new bool[n];
fill(isUsing,isUsing+n,false);
res=new bool[m];
fill(res,res+m,false);
sort(item,item+m);
sort(fama,fama+n);
for(int i=0;i<n;i++)
{
cin>>fama[i];
twFama+=fama[i];
}
for(int i=0;i<m;i++)
{
cin>>item[i];
}
for(int i=0;i<m;i++)
{
DFS(0,i,0,0);
if(res[i])
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
文章描述了一道关于利用给定的n个砝码和已知重量的m种物品,通过天平进行称重的问题。作者提供了一段C++代码,采用深度优先搜索(DFS)和剪枝策略来判断每个物品能否被正确称出。
310

被折叠的 条评论
为什么被折叠?



