zoj 3703+背包dp

题目链接:Happy Programming Contest

题解:先01背包把最大价值的所要解决的问题找出来,然后贪心把时间排下序解题时间需要小的排前面。没有考虑解题个数要最多。居然过了(是数据太水了?)。没想明白

#include<bits/stdc++.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define ll long long
#define pb push_back
using namespace std;
const int N=800010;
const int INF=1<<30;
const ll inf=1e18;
const int maxn=2e5+10;
const int mod=1e9+7;
int n,m,t;
int pre[55][1000+10],dp[1000+10];
vector<int>ans;
struct node
{
    int a,w;
}st[1000+10];
ll sum=0,tmp=0;
int cnt=0;
void init()
{
    memset(dp,0,sizeof(dp));
    memset(pre,0,sizeof(pre));
    sum=0;tmp=0;cnt=0;ans.clear();
}
void dfs(int c,int v)
{
    if(c==0)
    {
        return;
    }
    if(pre[c][v])
    {
        cnt++;
        ans.pb(st[c].a);
        dfs(c-1,v-st[c].a);
    }
    else dfs(c-1,v);
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        init();
        int ron;
        scanf("%d %d",&ron,&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&st[i].a);
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&st[i].w);
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=ron;j>=st[i].a;j--)
            {
                if(dp[j]<dp[j-st[i].a]+st[i].w)
                {
                    dp[j]=dp[j-st[i].a]+st[i].w;pre[i][j]=1;
                }
            }
        }
        dfs(n,ron);
        sort(ans.begin(),ans.end());
        for(int i=0;i<ans.size();i++)
        {
            tmp+=ans[i];
            sum+=tmp;
        }
        printf("%d %d %lld\n",dp[ron],ans.size(),sum);
    }
    return 0;
}

 

posted @ 2018-05-09 19:58  lhclqslove  阅读(118)  评论(0编辑  收藏  举报