揹包問題——P6567 [NOI Online #3 入門組]買表

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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章