poj 1837 Balance -DP


题目链接http://poj.org/problem?id=1837

//思路:开一个G*(平衡度)的数组,DP找的就是状态,所以平衡度就是该状态~~表示DP真的不好~~继续DP吧!
//dp[i][j] 表示在挂满前i个物体的时,平衡度为j的挂法的数量。j为正表示右面重。
//最极端的情况是所有物体都挂在最远端,因此平衡度最大值为15*20*25=7500。原则上就应该有dp[ 0..20 ][-7500 .. 7500 ]。
//因此做一个处理,使得数组开为 dp[0.. 20][0..15000]。
//状态方程:dp[i][j]=sigma( dp[i-1][ j-c[k]*w[i] ] )

//memory 1396KB time 16ms
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
using namespace std;
int dp[21][15001];
int main()
{
    int C,G,c[21],g[21];
    while(scanf("%d%d",&C,&G)!=EOF)
    {
        for(int i=1;i<=C;i++)
           scanf("%d",&c[i]);
        for(int i=1;i<=G;i++)
           scanf("%d",&g[i]);

        memset(dp,0,sizeof(dp));
        dp[0][7500]=1;

        for(int i=1;i<=G;i++)
          for(int j=0;j<=15000;j++)
          if(dp[i-1][j])
             for(int k=1;k<=C;k++)
             dp[i][j+g[i]*c[k]]+=dp[i-1][j];

        printf("%d\n",dp[G][7500]);
    }
    return 0;
}

另外一种方法:

//POJ1837 DP balance
#include<cstdio>
#include<cstring>

int dp[15010],tp[15010];
int c[30];
int g[30];
int main () 
{
    int C,G;
    while(~scanf("%d%d",&C,&G))
    {
        memset(c,0,sizeof(c));
        memset(g,0,sizeof(g));
        for(int i=0;i<C;i++)//从1开始 
        {
            scanf("%d",&c[i]);
        }
        for(int j=0;j<G;j++)
        {
            scanf("%d",&g[j]);
        }
        memset(dp,0,sizeof(dp)) ;
        dp[7500]=1;//表示不用物体时,平衡度为0有一种挂法
        
        for(int i=0;i<G;i++)
        {
            memcpy(tp,dp,sizeof(tp));
            memset(dp,0,sizeof(dp));
            for(int j=-7500;j<=7500;j++)
            {
                for(int k=0;k<C;k++)
                {
                    dp[j+7500]+=tp[j+7500-g[i]*c[k]];
                }
            }
        }
        printf("%d\n",dp[7500]);
    }
    return 0;
}

 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值