一道非常经典的题目
题目大意
给出N个作业的截至日期,和N个作业不交所扣掉的分数,要求输出扣除分数做少的方案。
正确的策略是:
- 扣除分数大的先做
- 扣除分数相同,先截止的先做
- 做一件事的时候,从截止时间开始向第一天遍历,如果当天没有被作业占据则标记为占据。做这件事的日期越大越好。
- 如果不能满足3的条件,则为不能完成
1 #include <iostream> 2 #include <algorithm> 3 #include <string> 4 #include <string.h> 5 6 #define MAX 1010 7 8 using namespace std; 9 int V[MAX]; 10 int E[MAX]; 11 bool t[MAX]; 12 int order[MAX]; 13 14 void init() 15 { 16 memset(t,0,MAX * sizeof(bool)); 17 return ; 18 } 19 20 bool cmpA (int a ,int b) 21 { 22 if(V[a] > V[b]) 23 { 24 return 1; 25 } 26 else if(V[a] == V[b] && E[a] < E[b]) 27 { 28 return 0; 29 } 30 else 31 return 0; 32 } 33 34 int main() 35 { 36 int T; 37 while(~scanf("%d",&T)) 38 { 39 for (int i = 0; i < T; ++i) 40 { 41 init(); 42 int N; 43 int All = 0; 44 int ans = 0; 45 scanf("%d",&N); 46 for (int j = 0; j < N; ++j) 47 { 48 scanf("%d",&E[j]); 49 } 50 for (int j = 0; j < N; ++j) 51 { 52 scanf("%d",&V[j]); 53 All = All + V[j]; 54 order[j] = j; 55 } 56 ////////////////////////// 57 sort(order,order + N,cmpA); 58 ///////////////////////////// 59 ////////////////////////////// 60 for (int j = 0; j < N; ++j) 61 { 62 int event = order[j]; 63 bool flag = 0; 64 for (int k = E[event]; k >= 1; k--) 65 { 66 if(!t[k]) 67 { 68 ans = ans + V[event]; 69 t[k] = 1; 70 flag = 1; 71 } 72 if(flag) break; 73 } 74 } 75 /////////////////////////// 76 cout << All - ans << endl; 77 78 } 79 } 80 return 0; 81 }
时间: 2024-10-15 02:52:29