hihoCoder 1272 买零食

来源:互联网 发布:建筑行业 失业 知乎 编辑:程序博客网 时间:2024/04/29 00:31

描述

小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可以获得最大的渴望度之和。

样例输入
140.5 64.5 75.0 42.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