lightoj 1235 Coin Change (IV)
2014-07-31 10:40
381 查看
题目大意 : 有N个硬币(N<=18),问能否在每个硬币使用不超过两次的情况下支付正好K的面额。
思路 : dfs构造出用这些硬币用前一半能支付的所有费用和后一半能支付的所有费用。之后排序,枚举前一半的每个面值在第二个里面二分寻找即可。(或者用set保存)。
想到一半一半处理然后综合,其实这个题跟1127很类似。以至于我刚开始一直想着怎么用状态压缩去求所有的情况。这里每个硬币可以用一次、两次、零次。而那个题是可以用一次或者零次。所以这个题就不能用01表示了。所以也就不能用状态压缩了。
没有办法,只有搜索了。。然后枚举+二分。。
int a[maxn];
vector<int> va,vb;
void pushback(int sum,int l,int r){
if(l==r){
va.pb(sum);
return;
}
for(int i=0;i<3;i++)
pushback(sum+a[l]*i,l+1,r);
}
void pushback2(int sum,int l,int r){
if(l==r){
vb.pb(sum);
return;
}
for(int i=0;i<3;i++)
pushback2(sum+a[l]*i,l+1,r);
}
int main(){
int T;
scanf("%d",&T);
for(int tt=1;tt<=T;tt++){
va.clear();
vb.clear();
int n,k;
scanf("%d%d",&n,&k);
int ta=n>>1;
int tb=n-ta;
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
pushback(0,0,ta);
pushback2(0,ta,n);
sort(va.begin(),va.end());
sort(vb.begin(),vb.end());
bool can=false;
for(size_t i=0;i<vb.size();i++){
if(*lower_bound(va.begin(),va.end(),k-vb[i])==k-vb[i]){
can=true;
break;
}
}
printf("Case %d: ",tt);
if(can)puts("Yes");
else puts("No");
}
return 0;
}
思路 : dfs构造出用这些硬币用前一半能支付的所有费用和后一半能支付的所有费用。之后排序,枚举前一半的每个面值在第二个里面二分寻找即可。(或者用set保存)。
想到一半一半处理然后综合,其实这个题跟1127很类似。以至于我刚开始一直想着怎么用状态压缩去求所有的情况。这里每个硬币可以用一次、两次、零次。而那个题是可以用一次或者零次。所以这个题就不能用01表示了。所以也就不能用状态压缩了。
没有办法,只有搜索了。。然后枚举+二分。。
int a[maxn];
vector<int> va,vb;
void pushback(int sum,int l,int r){
if(l==r){
va.pb(sum);
return;
}
for(int i=0;i<3;i++)
pushback(sum+a[l]*i,l+1,r);
}
void pushback2(int sum,int l,int r){
if(l==r){
vb.pb(sum);
return;
}
for(int i=0;i<3;i++)
pushback2(sum+a[l]*i,l+1,r);
}
int main(){
int T;
scanf("%d",&T);
for(int tt=1;tt<=T;tt++){
va.clear();
vb.clear();
int n,k;
scanf("%d%d",&n,&k);
int ta=n>>1;
int tb=n-ta;
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
pushback(0,0,ta);
pushback2(0,ta,n);
sort(va.begin(),va.end());
sort(vb.begin(),vb.end());
bool can=false;
for(size_t i=0;i<vb.size();i++){
if(*lower_bound(va.begin(),va.end(),k-vb[i])==k-vb[i]){
can=true;
break;
}
}
printf("Case %d: ",tt);
if(can)puts("Yes");
else puts("No");
}
return 0;
}
相关文章推荐
- lightoj 1235 Coin Change (IV)(折半枚举)
- LightOJ 1235 - Coin Change (IV) (折半枚举)
- Lightoj 1235 - Coin Change (IV) 【二分】
- Lightoj 1235 - Coin Change (IV) 【二分】
- 1235 - Coin Change (IV)
- lightoj1018 - Brush (IV) - 状压DP
- LightOJ - 1232 - Coin Change (II)
- LightOJ 1231 Coin Change (I) (线性dp 背包计数)
- lightoj1018 - Brush (IV)【状压dp】
- 1232 - Coin Change (II) Lightoj 转移为等差
- lightoj 1232 - Coin Change (II) 完全背包
- lightoj 1018 - Brush (IV) 【状压dp】
- lightoj 1233 - Coin Change (III) 多重背包+二进制优化
- LightOJ 1232 - Coin Change (II) 【完全背包】
- LightOJ 1018 - Brush (IV)
- [LightOJ 1018] Brush (IV) (状压DP)
- lightoj 1018 - Brush (IV) 状压DP
- LightOj 1231 Coin Change (I)(部分背包)
- lightoj 1018 - Brush (IV)
- LightOj 1231 Coin Change (II)(完全背包)