https://www.luogu.com.cn/problem/P6567
思路:
給了錢幣數
錢幣分爲面額和張數
還有幾塊表
感覺就是有n個物品,每個物品的大小和數量已知,求能不能正好放進這個揹包
區別:
動態方程:
完全揹包的方程是將其轉換爲01揹包後,求在有限的容量內,以特定的物品能產生的最大值
即
for(int i=1;i<=n;i++)
{
for(int j=m;j>=a[i];j--)
{
if(dp[j-a[i]]+c[i]>dp[j]){
dp[j]=dp[j-a[i]]+c[i];
}
}
}
這道題我們想要通過幾次運算後看它能不能回到“原點”
即
dp[0]=1;
for(int i=1;i<=s;i++){//s爲物品數量
//進來一個物品
for(int j=pur;j>=a[i];j--){
if(dp[j-a[i]]==1){//如果它前面這步能回到原點
dp[j]=1;//那麼它也可以
}
}
}
if(dp[pur]==dp[0]){
cout<<"Yes";
break;
}
答案
int n,m;
cin>>n>>m;
int a[n+1],b[n+1];
//輸入+轉換
int s=0;//轉換後物品數量,爲定義數組用
for(int i=1;i<=n;i++){
cin>>a[i]>>b[i];
s+=b[i];
}
int p[s+1];
int q=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=b[i];j++){
p[q++]=a[i];
}
}
for(int k=1;k<=m;k++){
int pur;
cin>>pur;
//pur=3
int dp[pur+1];
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int i=1;i<=s;i++){
for(int j=pur;j>=p[i];j--){
if(dp[j-p[i]]==1){
dp[j]=1;
}
}
if(dp[pur]==1){
cout<<"Yes";
break;
}
}
if(dp[pur]==0){
cout<<"No";
}
cout<<endl;
}