hihoCoder 1272 买零食

描述

小Ho很喜欢在课间去小卖部买零食。然而不幸的是,这个学期他又有在一教的课,而一教的小卖部姐姐以冷若冰霜著称。第一次去一教小卖部买零食的时候,小Ho由于不懂事买了好一大堆东西,被小卖部姐姐给了一个“冷若冰霜”的眼神,食欲都下降了很多。

从那以后,小Ho就学乖了,去小卖部买东西只敢同时买3包以内的零食,并且价格加起来必须是5的整数倍,方便小卖部姐姐算价格。

但是小Ho不擅长计算,所以他把小卖部里所有零食的价格以及他对这个零食的渴望度都告诉了你,希望你能够帮他计算出在不惹恼小卖部姐姐的前提下,能够买到零食的渴望度之和最高是多少?

输入

每个输入文件包含多组测试数据,在每个输入文件的第一行为一个整数Q,表示测试数据的组数。

每组测试数据的第一行为一个正整数N,表示小卖部中零食的数量。

接下来的N行,每行为一个正实数A和一个正整数B,表示这种零食的价格和小Ho对其的渴望度。

一种零食仅有一包。

对于100%的数据,满足1 <= Q <= 10,1<=N<=50,0<A<=10,1<=B<=100。

对于100%的数据,满足A的小数部分仅可能为0.5或0。

输出

对于每组测试数据,输出一个整数Ans,表示小Ho可以获得最大的渴望度之和。

样例输入
1
4
0.5 6
4.5 7
5.0 4
2.0 9
样例输出
17





在拿到题目的第一时间我就觉得是一题dp ,一段时间后,我码出了后面的代码:

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

int  val[55];
int  data[55];
int  dp[55][5][5005];

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        memset(dp,0,sizeof(dp));
        int i,j,k;
        int sum=0;
        for(i=1;i<=n;i++)
        {
            double f1;
            scanf("%lf %d",&f1,&data[i]);
            val[i]=(int )(10*f1);
            sum+=val[i];
        }

        dp[1][1][val[1]]=data[1];
        for(i=2;i<=n;i++)
        {
            dp[i][1][val[i]]=data[i];
            for(k=2;k<=3;k++)
            {
               for(j=val[i];j<=sum;j+=5)
               {
                   int maxn=0;
                   for(int h=1;h<i;h++)
                   {
                       if(dp[h][k-1][j-val[i]] >maxn )
                        maxn=dp[h][k-1][j-val[i]];
                   }
                   if(maxn)
                   dp[i][k][j]+=(maxn+data[i]);
               }
            }

        }

        int ans=0;
        for(i=0;i<=sum;i+=50)
        {
            for(j=1;j<=n;j++)
            {
                for(k=1;k<=3;k++)
                  if(dp[j][k][i]>ans)
                    ans=dp[j][k][i];
            }
        }

        printf("%d\n",ans);

    }
    return 0;
}

然而之后我一不小心看到了别人的代码:

#include <set>
#include <map>
#include <list>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define CLR(a,b) memset(a,b,sizeof(a))
#define PB(x) push_back(x)

const int maxn = 100 + 5;
int qian[maxn];
int num[maxn];

int main(){
    int Q;
    cin>>Q;
    while(Q--){
        int n;
        cin>>n;
        for(int i = 0;i < n;i ++) {
            double mm;
            scanf("%lf%d",&mm,&num[i]);
            qian[i] = mm * 10;
        }
        int ans = 0;
        for(int i = 0;i < n;i ++) {
            if(qian[i] % 50 == 0) ans = max(ans,num[i]);
        }
        for(int i = 0;i < n;i ++) {
            for(int j = i + 1;j < n;j ++){
                if((qian[i] + qian[j]) % 50 == 0)ans = max(ans,num[i] + num[j]);
            }
        }
        for(int i = 0;i < n;i ++) {
            for(int j = i + 1;j < n;j ++) {
                for(int k = j + 1;k < n;k ++) {
                    if((qian[i] + qian[j] + qian[k]) % 50 == 0) {
                        ans = max(ans, num[i] + num[j] + num[k]);
                    }
                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

直接穷举每种可能性就行了= = 

给自己提个醒,不要掉入思维惯性中去了,看到买东西就想到dp……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值