poj 1837-Balance

http://poj.org/problem?id=1837

刚开始学习动态规划,以前只做过几道,比如最少零钱数问题啥的,这是个大坑,得好好练练。

此题看完一点也找不到思路。参考别人的代码写出来的,惭愧啊。

不过大牛们的代码都是把7500做为平衡点,个人认为没有必要,因为重量最大25,杠杆最长15,个数最多虽然是20个,但是为了保持平衡最多10个在一边,最关键一点,题目说了It is guaranteed that will exist at least one solution for each test case at the evaluation.即至少会有1个解,所以25×15×10=3750,这个数据做为平衡点就够了。

状态转化方程为dp[i+1][j+c[k]*g[i]] += dp[i][j],i代表层数,加一个砝码层数就多一层,j代表重量平衡的位置,因为数组不能有负数所以就有了上面的估计平衡点的大小。只要上一层的某一个重量的数组值非0就要根据方程状态转化。到最后只需要取你当初设置的平衡点的数组值就可以了。

理解完这题真的觉得DP不容易,看代码看的懂,自己想却想不出来,要好好加油了。

#include<cstdio>
#include<ctype.h>
#include<algorithm>
#include<iostream>
#include<string.h>
using namespace std;
int dp[21][7500+1];


int main()
{
    int C,G,i,j,k;
    int c[21],g[21];
    cin>>C>>G;
    for(i = 0; i < C; i++)
        cin>>c[i];
    for(i = 0; i < G; i++)
        cin>>g[i];
    memset(dp,0,sizeof(dp));
    dp[0][3750] = 1;
    for(i = 0; i < G; i++)
        for(j = 0; j < 7500; j++)
        {
            if(dp[i][j] != 0)
                for(k = 0; k < C; k++)
                    dp[i+1][j+c[k]*g[i]] += dp[i][j];
        }
    cout<<dp[G][3750]<<endl;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值