# 6-4 Programming Contest (30分)

Bob will participate in a programming contest. There are altogether n problems in the contest. Unlike in PAT (Programming Ability Test), in a programming contest one can not obtain partial scores. For problem i, Bob will need time[i] to solve it and obtains the corresponding score[i], or he may choose not to solve it at all. Bob will be happy when he obtains a total score no less than happy_score. You are supposed to find the minimum time needed for Bob to be happy. The function need_time must return the minimum time, or -1 if it is impossible for Bob to obtain a score no less than happy_score.

## Format of function:

int need_time(const int time[], const int score[], int happy_score, int n);


Here n (1≤n≤ MAXN) is the number of problems; happy_score (1≤ happy_score ≤ MAXS) is the minimum score for Bob to be happy; time[] is the array to store time[i] (1≤time[i]≤100) which is the time to solve problem i; score[] is the array to store score[i] (1≤score[i]≤100) which is the score Bob gets for solving problem i.

## Sample program of judge:

#include <stdio.h>

#define MAXN 10
#define MAXS 1000

int need_time(const int time[], const int score[], int happy_score, int n);

int main() {
int n, i, happy_score;
int time[MAXN], score[MAXN];
scanf("%d %d", &n, &happy_score);
for (i = 0; i < n; ++i)
scanf("%d", &time[i]);
for (i = 0; i < n; ++i)
scanf("%d", &score[i]);
printf("%d\n", need_time(time, score, happy_score, n));
return 0;
}

/* Your function will be put here */


## Sample Input:

6 121

84 87 78 16 94 38
87 93 50 22 63 28


## Sample Output:

125


## 思路：

1.开心值总和 >= happy_score
2.所花时间总和最少

1.开心值之和<=happy_score
2.所花的时间总和最多

happy_score就是背包的空间，题目的开心值就是放入背包的物品的体积，而题目的耗时就是每个物品的价值。最后的耗时就是不做的题目的最大耗时，再总时间作个差就得到要做的题目的最少耗时。

## 源码：

int max(int a,int b)
{
return a>b?a:b;
}
int need_time(const int time[], const int score[], int happy_score, int n)
{
int i;
int sum=0;
int sum_time=0;
int min_score=MAXS;
for(i=0;i<n;i++)
{
sum+=score[i];
sum_time+=time[i];
min_score=score[i]<min_score?score[i]:min_score;
}
if(sum<happy_score)return -1;//所有题目都做也不能达到开心值

int dp[sum-happy_score+1][n+1];//dp[x][y]：在剩余x空间的背包放入前y件物品所能获得的最大价值

for(int i=0;i<=sum-happy_score;i++)
for(int j=0;j<=n;j++)
dp[i][j]=0;

for(int j=min_score;j<=sum-happy_score;j++)
{
for(int i=1;i<=n;i++)
{
if(j>=score[i-1])
//剩余背包空间足够放下第i件物品,则在放与不放中选择价值最大的情况
dp[j][i]=max(dp[j][i-1],time[i-1]+dp[j-score[i-1]][i-1]);
else
//剩余背包空间不足放下第i件物品
dp[j][i]=dp[j][i-1];
}
}

if(sum_time==dp[sum-happy_score][n])
return -1;
else
return sum_time-dp[sum-happy_score][n];
}


int max(int a,int b)
{
return a>b?a:b;
}
int need_time(const int time[], const int score[], int happy_score, int n)
{
int i;
int sum=0;
int sum_time=0;
int min_score=MAXS;
for(i=0;i<n;i++)
{
sum+=score[i];
sum_time+=time[i];
min_score=score[i]<min_score?score[i]:min_score;
}
if(sum<happy_score)return -1;

int dp[sum-happy_score+1];

for(int i=0;i<=sum-happy_score;i++)
{
dp[i]=0;
}

int v=sum-happy_score;
for(int i=1;i<=n;i++)
{
for(int k=v;k>=score[i-1];k--)
{
dp[k]=max(dp[k],dp[k-score[i-1]]+time[i-1]);
}
}

if(sum_time==dp[v])
return -1;
else
return sum_time-dp[v];
}


©️2019 CSDN 皮肤主题: 黑客帝国 设计师: 上身试试 