1. 程式人生 > >P2347 砝碼稱重-DP方案數-bitset

P2347 砝碼稱重-DP方案數-bitset

方案 follow www. tps 一個 vector 集合 max 簡單

P2347 砝碼稱重

  • DP做法 : 轉化為 01背包。 進行方案數 更新。最後統計種類。
  • #include<bits/stdc++.h>
    using namespace std;
    #define maxn 1234
    int n,k,dp[maxn],len,sum,ans;
    int a[11]= {0,1,2,3,5,10,20};
    vector<int>p;
    int main()
    {
        for(int i=1; i<=6; i++)
        {
            scanf("%d",&k);
            for(int j=0; j<k; j++)
            {
                p.push_back(a[i]);
                sum+=a[i];
            }
        }
        dp[0]=1;
        len=p.size();
        for(int i=0; i<len; i++)
            for(int j=sum; j>=p[i]; j--)
                dp[j]+=dp[j-p[i]];
        for(int i=1; i<=sum; i++)
            if(dp[i])ans++;
        printf("Total=%d\n",ans);
        return 0;
    }
    

      

    bitset 做法 :
    因為 bitset 只能存 00 和 11 ,我們可以讓第 ii 位為 11 來表示可以表示出 ii 這個值。
    bitset能對某一位賦值,我們初始定義 Bitset[0]=1Bitset[0]=1,表示可以表示出 00
    當我們加入一個新的砝碼的時候,我們將這個砝碼加入 bitset ,即進行如下的操作
    Bitset |= Bitset << w[i]Bitset∣=Bitset<<w[i]
    簡單理解就是已有的所有能表示出的值都加上 w_iwi? 再與原集合取並集。
    最後我們統計 bitset 中有多少個 11 即可,可以使用自帶函數 Bitset.count()Bitset.count() 完成。

  • #include<bits/stdc++.h>
    using namespace std;
    #define maxn 1234
    int dp[maxn];
    int a[11]= {0,1,2,3,5,10,20};
    bitset<1010>s;
    int main()
    {
        for(int i=1; i<=6; i++)scanf("%d",&dp[i]);
        s[0]=1;
        for(int i=1; i<=6; i++)
            for(int j=0; j<dp[i]; j++)
                s|=s<<a[i];
        printf("Total=%d\n",s.count()-1);
        return 0;
    }
    

      

P2347 砝碼稱重-DP方案數-bitset