饭卡---hdu2546(01背包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2546

这是一个变形的01背包问题,首先如果金额小于5元,剩余金额不变,为已有金额。如果大于等于5元
我们先用5元买最贵的菜。然后用剩下的钱买其他的菜这时就是一个典型的01背包问题了;
求出最大的花费,然后用总金额减去最大的花费即为剩余金额。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define INF 0xfffffff
#define N 1005
int a[N], dp[N][N];

int main()
{
    int n, m;
    while(scanf("%d", &n), n)
    {
        for(int i=1; i<=n; i++)
            scanf("%d", &a[i]);
        scanf("%d", &m);
        if(m<5)
        {
            printf("%d\n", m);
            continue;
        }
        m-=5;
        sort(a+1, a+n+1);
        for(int i=1; i<n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                dp[i][j] = dp[i-1][j];///千万不能忘的;
                if(j>=a[i])
                    dp[i][j] = max(dp[i-1][j], dp[i-1][j-a[i]]+a[i]);
            }
        }
        printf("%d\n", m+5-dp[n-1][m]-a[n]);
    }
    return 0;
}
二维数组

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define INF 0xfffffff
#define N 1005
int a[N], dp[N];

int main()
{
    int n, m;
    while(scanf("%d", &n), n)
    {
        memset(a, 0, sizeof(a));
        memset(dp, 0, sizeof(dp));
        for(int i=1; i<=n; i++)
            scanf("%d", &a[i]);
        scanf("%d", &m);
        if(m<5)
        {
            printf("%d\n", m);
            continue;
        }
        m-=5;
        sort(a+1, a+n+1);
        for(int i=1; i<n; i++)
        {
            for(int j=m; j>=a[i]; j--)
            {
                dp[j] = max(dp[j], dp[j-a[i]]+a[i]);
            }
        }
        printf("%d\n", m+5-dp[m]-a[n]);
    }
    return 0;
}
一维数组

 

 

 

 
posted @ 2015-11-18 15:37  西瓜不懂柠檬的酸  Views(1207)  Comments(0Edit  收藏  举报
levels of contents