T1.P1776 宝物筛选
思路:
看上去就像多重背包。但是要用二进制拆分将第i种物品分成若干件物品,其中每件物品有一个系数,这件物品的费用和价值均是原来的费用和价值乘以这个系数。例如,如果p[i]为13,就将这种物品分成系数分别为1 , 2 , 4 , 6 的四件物品,则这四件物品的费用为kw[i]、价值为kv[i]。(k是物品的数目,而w[i]和v[i]分别为费用和价值)。这样我们就把一件物品拆分为多个物品,然后就可以使用01背包求解。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int a,b,c,tmp;
int n,maxw,dp[N],w[N],v[N];//n->种类,maxw->载重,w[]->重量,v[]->价值
int main()
{
cin>>n>>maxw;
for(int i=1;i<=n;i++)
{
cin>>a>>b>>c;
for(int j=1;j<=c;j<<=1)//二进制拆分
{
tmp++;
v[tmp]=j*a;
w[tmp]=j*b;
c-=j;
}
if(c)
{
tmp++;
v[tmp]=c*a;
w[tmp]=c*b;
}
}
for(int i=1;i<=tmp;i++)
for(int j=maxw;j>=w[i];j--)
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
cout<<dp[maxw];
}
T2.P1555 尴尬的数字
思路:
二进制每一位数只有1或0,挨个判断是不是他的那一位错误,因为正确的只有写错的三进制数有一位区别,记录后转换为三进制,判断只有一位时输出即可。emm就是暴力枚举的感觉
代码:
#include<iostream>
#include<string>
#include<cstdio>
using namespace std;
string s2,s3;
int x3[101];
int radix(string s,int n)
{
int t=0,u=s.size(),t1=1;
for(int i=u-1;i>=0;i--)
{
t=t+(s[i]-'0')*t1;
t1*=n;
}
return t;
}
int main()
{
cin>>s2>>s3;
int t3=s3.size(),t2=s2.size(),t=0;
for(int i=0;i<t3;i++)
{
char s=s3[i];
for(int j=0;j<=2;j++)
{
s3[i]=char(j+'0');
x3[++t]=radix(s3,3);
}
s3[i]=s;
}
for(int i=0;i<t2;i++)
{
int f;
char s=s2[i];
if(s2[i]=='0')
{
s2[i]=char(1+'0');
f=radix(s2,2);
s2[i]=s;
}
else
{
s2[i]=char(0+'0');
f=radix(s2,2);
s2[i]=s;
}
for(int j=1;j<=t;j++)
{
if(f==x3[j])
{
cout<<f;
return 0;
}
}
}
}```
T3.P8845小卡和质数
思路:
在二进制下只有末尾不同的数异或才是1,要满足这个条件,就需要两数奇偶性不同,则两个质数为一奇一偶。偶数中只有2是质数,而易知在其它质数中只有 3和2的异或值为1.最终得到两个质数只能是 3和 23是第 2个质数,2是第一个质数,则x和y为2和 1
还要注意两数可能调换位置。
代码:
#include<bits/stdc++.h>
using namespace std;
int t,a,b;
int main()
{
cin>>t;
while(t--)
{
cin>>a>>b;
if((a==2&&b==1)||(a==1&&b==2))cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}