Description
Input
Each test case start with a positive integer N(1<=N<=1000) which indicate the number of homework.. Then 2 lines follow. The first line contains N integers that indicate the deadlines of the subjects, and the next line contains N integers that indicate the reduced scores.
Output
Sample Input
3 3 3 3 3 10 5 1 3 1 3 1 6 2 3 7 1 4 6 4 2 4 3 3 2 1 7 6 5 4
Sample Output
0 35
问题描述:Ignatius比赛回来之后,每位老师给Ignatius一个交作业的最后期限,如果交不上去就扣分。每门作业都要一天时间完成,求最少扣多少分。先输入一个T表示有T组测试数据,接下来每组数据先输入一个N,代表有N个作业,然后输入两行,第一行表示每门作业要交的日期,第二行表示对应的如果不交这门作业要扣的分数。输出要扣的最少分数。
贪心问题:
把限制天数从小到大排序,若限制天数相同时,把扣分的数值按从大到小排序。
定义一个一位数组。
伪代码(对最小值的讨论):
if(限制天数不小于当前天数) //此时不会扣分
{
用数组进行标记;
当前天数增加;
}
else //此时要面临扣分情况
{
寻找从0到当前天数的最小值,累加。
}
//AC
#include<stdio.h> #include<string.h> #include<math.h> #include<iostream> #include<algorithm> #include<string> using namespace std; struct P //x是限制天数 { int x,y; } a[1001]; bool comp(P X,P Y) { if(X.x==Y.x) return X.y>Y.y; return X.x<Y.x; } int main() { int s[1001]; //标记使用 int n,i,j,m,k; cin>>n; while(n--) { memset(s,0,sizeof(s)); cin>>k; for(i=0; i<k; i++) scanf("%d",&a[i].x); for(i=0; i<k; i++) cin>>a[i].y; sort(a,a+k,comp); int sum=0,d=1,min,t; for(i=0; i<k; i++) { if(a[i].x>=d) //不会扣分(带个特殊值,例如第三组,第一个4通过以后d=5,所以剩下的4都不能通过,到6才可以) { s[i]=1; d++; } else //寻找最小的情况,进行累加 { min=a[i].y; t=i; for(j=i-1; j>=0; j--) if(s[j]==1&&a[j].y<min) //s[j]=1证明该数属于不会扣分类 { min=a[j].y; t=j; } sum+=a[t].y; a[t].y=a[i].y; //交换(可能接下来讨论的时候可能变最小) } } cout<<sum<<endl; } }