1.P1776 宝物筛选 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
解析:
明显的背包DP,但本题数据较大,所以要进行优化。可以用二进制优化来处理。
多重背包的原理就是将一个物品不同个数当做新物品来处理,我们用二进制优化处理这一步。
对于一个数,可以用不大于该数的2的n次幂加上余数组成。例如将19拆分成2,4,8,16,3,就可以用这五个数表示1~19的所有数。
代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; int f[1000005]; int v[1000005],wi[1000005]; int cnt=1; int main() { int n,w; scanf("%d%d",&n,&w); for(int i=1;i<=n;++i) { int a,b,m; scanf("%d%d%d",&a,&b,&m); //二进制优化代替原拆分 for(int j=1;j<=m;j*=2) { v[++cnt]=j*a,wi[cnt]=j*b; m-=j; } if(m) v[++cnt]=a*m,wi[cnt]=b*m; } for(int i=1;i<=cnt;++i)//多重背包 for(int j=w;j>=wi[i];--j) f[j]=max(f[j],f[j-wi[i]]+v[i]); printf("%d\n",f[w]); return 0; }
2.P1555 尴尬的数字 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
解析:
考察进制转换。我们将给出的二进制数变一位在转化为三进制数,将次三进制数与给出的三进制数比较,如果只差一位,那么就是这个数。题目给出答案只有一个,那么不必再考虑其他问题。
代码:
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; int a[50],b[50],c[50]; long long int mid; int cnt1,cnt2; void read1() { char k; while((k=getchar())!='\n') a[++cnt1]=k-'0'; } void read2() { char k; while((k=getchar())!='\n') b[++cnt2]=k-'0'; } void jin2() { int tot=1; while(a[tot]==0) ++tot; int k=1;mid=0; for(int i=cnt1;i>=tot;--i) { mid+=a[i]*k; k*=2; } } void jin3(int n) { int t=cnt2; while(n) { c[t--]=n%3;n/=3; } } int main() { read1();read2(); for(int i=1;i<=cnt1;++i) { if(a[i]==1) { a[i]=0;jin2();a[i]=1; } else if(a[i]==0) { a[i]=1;jin2();a[i]=0; } jin3(mid); int cnt=0; for(int i=1;i<=cnt2;++i) { if(b[i]!=c[i]) ++cnt; if(cnt>1) break; } if(cnt==1) { printf("%lld",mid);break; } } return 0; }
3.P8845 [传智杯 #4 初赛] 小卡和质数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
解析:
要想异或值为1,那必须满足二进制下只有末位不同,二进制下末位不同则必定一奇一偶。而质数中只有2这一个偶数,要想二进制下只有末位不同的质数只有3。所以两个质数异或为1只能一个2 ,一个3。
代码:
#include<iostream> #include<cstdio> using namespace std; int main() { int T;scanf("%d",&T); while(T--) { int a,b; scanf("%d%d",&a,&b); if(a==1&&b==2||a==2&&b==1) printf("Yes\n"); else printf("No\n"); } return 0; }