直接暴力求解,比较满足条件的代金券哪个更优
#include <bits/stdc++.h>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
int min_n=n;
for(int i=1;i<=m;i++){
int a,b;
cin>>a>>b;
if(a<=n){
min_n=min(min_n,n-b);
}
}
cout<<min_n;
return 0;
}
如果是每一类的代金券只允许用一张,就是说可以无限的用代金券,但是每类只有一张
那么就需要用到二进制枚举 思路:有效到大给满足需求的代金券排序然后筛选出符合要求的
进行二进制枚举,如果在内层循环不符合要求直接剪枝,因为是升序排列前面的不符合要求后面的
一定不符合要求
#include <bits/stdc++.h>
using namespace std;
struct solve{
int a,b;
}t[105];
bool cmp(solve x,solve y){
return x.a<y.a;
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)cin>>t[i].a>>t[i].b;
sort(t+1,t+1+m,cmp);
int cnt=0;
for(int i=1;i<=m;i++){//去掉无法使用的代金券
if(t[i].a<=n)cnt++;
else
break;
}
int min_n=n;
int init_n=n;//保存第一次的n值方便每个循环重置
for(int mask=0;mask<(1<<cnt);mask++){
n=init_n;
bool flag=true;
for(int i=0;i<cnt;i++){
if(mask&(1<<i)){
if(t[i+1].a<=n){
n-=t[i+1].b;
if(n<0){
min_n=0;
cout<<min_n;
return 0;
}
}
else{flag=false;
break;}//剪枝因为是从小到大排的所以前面的不满足后面的肯定不满足
}
}if(flag)
min_n=min(min_n,n);
}
cout<<min_n;
return 0;
}