现在的位置: 首页 > 综合 > 正文

DP激情奉献(二)hdu1864

2013年07月13日 ⁄ 综合 ⁄ 共 1750字 ⁄ 字号 评论关闭

//本题大意:有许多张发票..每张发票上面给出了申请报销的种类的价格..要求在不超过limit的情况下.
//能够报销最多的钱..同时..对于每张发票..总额>1000时是无效的..单类价格总和>600时也是无效的..
//这个题目中..对于可以选择的发票里面..组成一个背包.对于每一张发票..要么不选.要么选..
//第一次自己做的时候..把浮点数转通过*100换成整型讲limit当成体积...每张发票的价格当成weight
//value也是这个价格..来计算在limit体积下能够装到的最大的value..
//虽然最后过了..但是以后尽量不要这么做..因为这里如果输入数据强一点..不全是.xx的,就必然过不了..
//所以这里采用dp[i][j] 的形式来记录.前i件商品中选择j件能够报销的最大值..
//那么..对于状态转移方程来说..dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]+value[i])..
//其实这样的方程在标准的0-1背包问题里面也是可以用的..但是因为那里没有浮点..而且又分了
//体积和价值..避免之后重复计算..采用了那样的式子......
//所以.以后要谨记了..对于浮点数状态的问题..不要先想着去转为整型的..要想着怎么样去选出整型的状态..
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<vector>
using namespace std;
const double end = 0.000001;
int main()
{
    bool vis[50];
    int n,k;
    double limit,value[50],dp[50];
    while(scanf("%lf%d",&limit,&n) && n != 0)
    {
        memset(vis,1,sizeof(vis));
        for(int i = 1 ; i <= n ; i++)
        {
            scanf("%d",&k);
            char h;
            double x,sum = 0,sum1 = 0,sum2 = 0,sum3 = 0;
            for(int j = 1 ; j <= k ; j++)
            {
                scanf(" %c:%lf",&h,&x);
                if(h == 'A')sum1 += x;
                if(h == 'B')sum2 += x;
                if(h == 'C')sum3 += x;
                if(h != 'A' && h != 'B' && h != 'C')vis[i] = 0;
                sum += x;
            }
            if(sum1 - 600 > end || sum2 - 600 > end || sum3 - 600 > end)vis[i] = 0;
            value[i] = sum;
        }
        memset(dp,0,sizeof(dp));
//        for(int i = 1 ; i <= n ; i++)//二维的版本为了更好的理解.
//        {
//            if(vis[i])
//            {
//                for(int j = 1 ; j <= i ; j++)
//                {
//                    dp[i][j] = max(dp[i-1][j-1] + value[i],dp[i-1][j]);
//                }
//            }
//        }
        double maxx = 0;
        for(int i = 1 ; i <= n ; i++)
        {
            if(vis[i])
            {
                for(int j = n ; j >= 1 ; j--)
                {
                    dp[j] = max(dp[j-1]+value[i],dp[j]);
                }
            }
        }
        for(int i = 1 ; i <= n ; i++)
        {
            if(dp[i] - limit < end && dp[i] - maxx > end)
                maxx = dp[i];
        }
        printf("%.2lf\n",maxx);
    }
}

抱歉!评论已关闭.