poj 1837 天平问题(01背包变种)

题意:给你n个挂钩,m个砝码,要求砝码都用上,问有多少中方案数

题解:对于这道题目的状态,我们定义一个变量j为平衡度,当j=0的时候,表明天平平衡。定义dp[i][j]表达的含义为使用前n个砝码的时候,平衡度为j的方案数。计数类型的背包,更新的时候把每个砝码的所有可能贡献(每个砝码可以放在不同的钩子上,每个钩子的离中点的距离不一致)都updata一下就ok了。关键是状态的抓取,然后这个计数背包的理解。

ac代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#define mt(a) memset(a,0,sizeof(a))
using namespace std;
int dp[26][16000];
int c[26];
int w[26];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>c[i];
    for(int i=1;i<=m;i++) cin>>w[i];
    mt(dp);
    dp[0][7500]=1;
    for(int i=1;i<=m;i++)
    {
        for(int j=0;j<=15000;j++)
        {
            for(int k=1;k<=n;k++)
            {
                if(dp[i-1][j]) dp[i][j+c[k]*w[i]]+=dp[i-1][j];
            }
        }
    }
    cout<<dp[m][7500]<<endl;
    return 0;
}

 

posted @ 2017-08-25 17:11  猪突猛进!!!  阅读(186)  评论(0编辑  收藏  举报