完全背包

完全背包问题

完全背包每件物品可选取的次数是没有上限的。这是用闫氏分析法完全背包的基本思路:

显然完全背包f[i,j]的状态和f[i,j-v]有关,优化一维内存需要从小到大枚举体积。

#include<bits/stdc++.h>
using namespace std;
const int N=1001;
int v[N],w[N],f[N];
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;++i)
        cin>>v[i]>>w[i];
    for(int i=1;i<=n;++i){
        for(int j=v[i];j<=m;++j){
            f[j]=max(f[j],f[j-v[i]]+w[i]);
        }
    }
    cout<<f[m]<<endl;   
    return 0;
}

900. 整数划分

思路:
将n个数字当作n个价值为i的物品,n也是背包体积。

#include<bits/stdc++.h>
using namespace std;
const int N=1010,mod=1e9+7;
int f[N];
int main(){
    int n;
    cin>>n;
    f[0]=1;
    for(int i=1;i<=n;++i){
        for(int j=i;j<=n;++j){
            f[j]+=f[j-i];
            f[j]%=mod;
        }
    }
    cout<<f[n]<<endl;
    return 0;
}

532. 货币系统

思路: 当一张币值能通过其他方法组合得到,说明此币值是不必要的。

#include<iostream>
#include<string.h>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<string>
#include<set>
#include<map>
using namespace std;
const int N=30000; 
int f[N],w[110];
int main(){
    int n;
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        memset(f,0,sizeof f);
        f[0]=1;
        for(int i=0;i<n;++i){
            scanf("%d",&w[i]);
            for(int j=w[i];j<N;++j){
                f[j]+=f[j-w[i]];
            }
        }
        int cnt=0;
        for(int i=0;i<n;++i){
            if(f[w[i]]>1) cnt++;
        }
        cout<<n-cnt<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jjl0229/p/12593800.html