ZOJ 3703 Happy Programming Contest 0-1背包 DP

ZOJ 3703 Happy Programming Contest

题目描述:

  题目链接:ZOJ 3703 Happy Programming Contest

题目大意:

  这是一道虐狗的题目。讲的是一对情侣在赛码场上,每道题对应不同颜色的气球,不同的气球对妹子的吸引力不同。在已知程序员做每道题所需的时间、比赛总时长以及每一个气球对妹子的吸引值。求在能力和时间允许的前提下,得到的气球对妹子吸引力的总值最大为多少。要求输出,吸引总值,解题数目,罚时。

解题思路:

  首先这个题很明显的是一个01背包。然而在求最大价值的同时,还要求计算解题数和罚时。因此,我考虑先对所有的题目进行01背包处理。然后在处理的过程中标记出最优方案中作出的题。在背包处理完之后,将做的题标记出来,按照耗时从小到大排序计算罚时即可。

复杂度分析:

时间复杂度: O(nt)
空间复杂度: O(nt)

AC代码:

#include 
#include 
#include 
#include 
#include 
using namespace std;

const int maxn = 1010;
int f[maxn];
int G[55][maxn];
int t[55];
int v[55];
int ord[55];
int n,tt;

int main()
{
    int N;
    cin >> N;
    while(N--)
    {
        scanf("%d%d",&tt,&n);
        for(int i = 1; i <= n; i++)scanf("%d",&t[i]);
        for(int i = 1; i <= n; i++)scanf("%d",&v[i]);
        memset(f,0,sizeof(f));
        memset(G,0,sizeof(G));
        for(int i = 1; i <= n; i++){
            for(int j = tt; j >= t[i]; j--){
                if(f[j] < f[j - t[i]] + v[i]){
                    f[j] = f[j - t[i]] + v[i];
                    G[i][j] = 1;
                }
            }
        }
        int cnt = 0;
        int i = n;
        int j = tt;
        while(i){
            if (G[i][j] == 1){
                ord[cnt++] = t[i];
                j -= t[i];
            }
            i--;
        }
        int pently = 0;
        int sum = 0;
        sort(ord,ord+cnt);
        for(int i = 0; i < cnt; i++) {
            sum += ord[i];
            pently = sum + pently;
        }
        printf("%d %d %d\n",f[tt],cnt,pently);
    }
}

/************************
2
300 10
10 10 10 10 10 10 10 10 10 10
1 2 3 4 5 6 7 8 9 10
300 10
301 301 301 301 80 140 60 301 301 301
1000 1000 1000 1000 1010 1000 1000 1000 1000 1000
****************************/

你可能感兴趣的:(动态规划)