poj 1837 Balance -DP

来源:互联网 发布:java启动exe程序 编辑:程序博客网 时间:2024/06/06 02:48


题目链接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;}

 



0 0
原创粉丝点击