[背包]poj1276 Cash Machine


题意:

求不大于所给金额且不超过所给面额的数量限制之下的,最大金额
所给金额不超10w,所给面额不过10种,每种面额不超1000张
val[]金额, n[]数量;

思路:

以前做过一遍,是多重背包的变形,dp[i]表示如果能达到i面额dp[i]就赋值1,否则为0

代码:

/************************************************************** 
    Problem: poj_1276
    User: soundwave 
    Language: C++ 
    Result: Accepted 
    Time: 563ms
    Memory: 1052KB 
****************************************************************/  
#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;
const int maxn=15;
const int maxm=100000+5;
int n[maxn], val[maxn];
int dp[maxm];//dp[i] 如果到达i面额就赋值1,背包的变形
int main(){
    int cash, N;
    int tmp;
    while(~scanf("%d%d", &cash, &N)){
        memset(dp,0,sizeof(dp));
        for(int i=0; i<N; i++)
            scanf("%d%d", &n[i], &val[i]);
        if(cash==0 || N==0){
            printf("0\n");
            continue;
        }
        dp[0]=1;
        for(int i=0; i<N; i++)
        for(int j=cash; j>=0; j--)
        if(dp[j]){
            for(int k=1; k<=n[i]; k++){
                tmp = j+k*val[i];
                if(tmp>cash) break;
                dp[tmp] = 1;
            }
        }
        for(int i=cash; i>=0; i--)
        if(dp[i]){
            printf("%d\n", i);
            break;
        }
    }
    return 0;
}
/*
735 3  4 125  6 5  3 350
633 4  500 30  6 100  1 5  0 1
735 0
0 3  10 100  10 50  10 10
--------------------------------
735
630
0
0
*/
反思:

翻了以前的记录,发现当时有种错误的思路,也写一下:

给出状态转移方程:f[i][v] = max{f[i-1][v-k*w[i]] + k}, 0<=k<=n[i];

前i种面额恰好填满v金额的最小数,不管是最小数还是最大数,只要这个数存在,找到距所给金额最接近的数即可

思维比较混乱,以至于这个思路无法继续下去,只好换成上面AC代码的思路
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值