zoukankan      html  css  js  c++  java
  • HDU2546(01背包变形)

    饭卡

    Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 18620    Accepted Submission(s): 6500


    Problem Description
    电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。
    某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。
     
    Input
    多组数据。对于每组数据:
    第一行为正整数n,表示菜的数量。n<=1000。
    第二行包括n个正整数,表示每种菜的价格。价格不超过50。
    第三行包括一个正整数m,表示卡上的余额。m<=1000。

    n=0表示数据结束。
     
    Output
    对于每组输入,输出一行,包含一个整数,表示卡上可能的最小余额。
     
    Sample Input
    1
    50
    5
    10
    1 2 3 2 1 1 2 3 2 1
    50
    0
     
    Sample Output
    -45
    32
    思路:先拿出5元钱购买最贵的东西,然后尽可能的将剩下的钱花完。求尽可能的将钱花完则转化为背包问题。
    /*
        Accepted    2546    31MS    1420K    525 B    G++    1340502116
    */
    #include"cstdio"
    #include"cstring"
    #include"algorithm"
    using namespace std;
    const int MAXN=1005;
    int n,W;
    int w[MAXN];
    int dp[MAXN];
    int main()
    {
        while(scanf("%d",&n)!=EOF&&n!=0)
        {
            memset(dp,0,sizeof(dp));
            for(int i=0;i<n;i++)    scanf("%d",&w[i]);
            scanf("%d",&W);
            if(W<5)
            {
                printf("%d
    ",W);
                continue;
            }
            sort(w,w+n);
            int V=W-5;
            for(int i=0;i<n-1;i++)
            {
                for(int j=V;j>=w[i];j--)    dp[j]=max(dp[j],dp[j-w[i]]+w[i]);
            }
            printf("%d
    ",W-dp[V]-w[n-1]);
        }
        
        return 0;
    }

     滚动数组:

    import java.util.Arrays;
    import java.util.Scanner;
    import static java.lang.System.out;
    public class Main{
        static Scanner in = new Scanner(System.in);
        static int MAXN=1005;
        static int n,m;
        static int[][] dp=new int[2][MAXN];
        static int[] w=new int[MAXN];
        public static void main(String[] args){
            
            while(in.hasNext())
            {
                Arrays.fill(dp[0], 0);
                n=in.nextInt();
                if(n==0)break;
                for(int i=0;i<n;i++)
                {
                    w[i]=in.nextInt();
                }
                m=in.nextInt();
                if(m<5)
                {
                    out.println(m);
                    continue;
                }
                Arrays.sort(w,0,n);
                m-=5;
                for(int i=0;i<n-1;i++)
                {
                    for(int j=0;j<=m;j++)
                    {
                        if(j<w[i])
                        {
                            dp[(i+1)&1][j]=dp[i&1][j];
                        }
                        else
                        {
                            dp[(i+1)&1][j]=Math.max(dp[i&1][j], dp[i&1][j-w[i]]+w[i]);
                        }
                    }
                }
                int res=m-dp[(n-1)&1][m]+5-w[n-1];
                out.println(res);
            }
        }
    }
  • 相关阅读:
    redis发布订阅
    redis学习笔记(面试题)
    redis安全 (error) NOAUTH Authentication required
    HDU3001 Travelling —— 状压DP(三进制)
    POJ3616 Milking Time —— DP
    POJ3186 Treats for the Cows —— DP
    HDU1074 Doing Homework —— 状压DP
    POJ1661 Help Jimmy —— DP
    HDU1260 Tickets —— DP
    HDU1176 免费馅饼 —— DP
  • 原文地址:https://www.cnblogs.com/program-ccc/p/5186506.html
Copyright © 2011-2022 走看看