NYOJ 747 蚂蚁的难题(三)(贪心+01背包)

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=747

题目大意:n 件食材,每件食材有一个美味度 Ai 和新鲜度 Bi , 如果蚂蚁在第t时刻将第i样食材烹饪成功,则得到Ai-t*Bi 的美味指数,求在时间 T 内完成的最大美味指数。

解题思路:若在P时刻,有两件食材需要烹饪,则:
先烹饪第一件食材:A[1]-(P+C[1])*B[1]+A[2]-(P+C[1]+C[2])*B[2];
先烹饪第二件食材:A[2]-(P+C[2])*B[2]+A[1]-(P+C[1]+C[2])*B[1];
所以我们可以先贪心,然后再用01背包来写。

AC代码:

#include
#include
#include
#include
#include
#define INF 0x3f3f3f3f
using namespace std;
struct node
{
    int a,b,c;
    int res;
} eg[55];
bool cmp(node x,node y)
{
    return x.c*y.b//如果第一件食材的烹饪时间大于第二件,即:
    //C[1]*B[2]
}
int dp[100001];
int main()
{
    int n,T;
    while(~scanf("%d%d",&T,&n))
    {
        int ans=0;
        memset(dp,0,sizeof(dp));
        for(int i=1; i<=n; i++)
            scanf("%d%d%d",&eg[i].a,&eg[i].b,&eg[i].c);
        sort(eg+1,eg+n+1,cmp);
        for(int i=1; i<=n; i++)
        {
            for(int j=min(eg[i].a/eg[i].b,T); j>=eg[i].c; j--)
            {
                //for(int j=T; j>=eg[i].c; j--)
            //第二层for循环可以优化,即最大时间为min(eg[i].a/eg[i].b,T)
                eg[i].res=eg[i].a-eg[i].b*j;
//                if(eg[i].res<=0)
//                    continue;
//                else
                dp[j]=max(dp[j],dp[j-eg[i].c]+eg[i].res);

                //   cout<
            }
            // cout<
        }
        for(int i=1; i<=T; i++)
            ans=max(dp[i],ans);
        printf("%d\n",ans);
    }
    return 0;
}
/*
6 3
200 5 1
300 4 2
300 5 6
*/

你可能感兴趣的:(贪心算法,nyoj,习题集)