别人说这是水题。。。
好吧我的尊严书只剩下封面了。。。
我的思路就是给个四个数组
一个用来存放deadline 一个用来存放punishment 一个用来存放rearrange 一个用来存放flag
rearrange数组对应的序号即为截止日期
然后遍历punishment
将对应截止日期的并且惩罚最大的元素放进去
做好flag=1 即已经被占用了
这是第一轮
然后再次遍历punishiment数组
如果flag=0 即没被访问
则看能不能放进rearrange里面
并且序号是小于截止日期的
再次做好flag
这是第二轮
最后,再次遍历punishment
如果未被访问并且大于rearrange某个元素并且截止日期也是比相应的序号要大 则再次修改
这是第三轮
然后敲代码就爆炸了,原因是思路太复杂而且操作起来都不方便
四个数组 反正我已经是被绕晕了
真的烦
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 1111
int a[maxn];//deadline
int b[maxn];//punishment
int c[maxn];//rearrange
int d[maxn];//flag
int main()
{
int t,i,j,n,v,h0,p,x;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
scanf("%d",&b[i]);
int m=max_element(a,a+n)-a;
int maxday=a[m];
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
for(i=0;i<n;i++)
{
j=a[i];
if(b[i]>c[j])
{c[j]=b[i];d[i]=1;}
}
for(i=1;i<=maxday;i++)
if(c[i]==0)
{
for(int h=0;h<n;h++)
{
if(d[h]==1)continue;
if(b[h]>c[i]&&a[h]>=i)
{c[i]=b[h];h0=h;}
}
d[h0]=1;
// for(p=0;p<n;p++)
// if(b[p]==c[i]&&d[p]==1)
// {
// v=p;break;
// }
// d[p]=0;
}
for(i=0;i<=maxday;i++)
printf("%d ",c[i]);
printf("\n");
for(i=0;i<n;i++)
{
if(d[i]==1)continue;
//int k=min_element(c+1,c+maxday)-c;
for(int y=0;y<=a[i];y++)
{
if(b[i]>c[y]&&a[i]>=y)
{
x=c[y];
c[y]=b[i];
d[i]=1;
for(j=0;j<n;j++)
if(b[j]==x&&a[j]==y)
d[v]=0;
}
}
}
for(i=0;i<=maxday;i++)
printf("%d ",c[i]);
printf("\n");
int tot=0;
for(i=0;i<n;i++)
if(d[i]==0)
tot+=b[i];
printf("%d\n",tot);
printf("\n");
}
return 0;
}
后来看了一下别人的代码
收下我的膝盖吧
定义一个结构体
按照 分数大的优先 相等的就截止日期小的排在前面
然后依次填充rearrange数组 序号还是截止日期
如果已经被填充 就去找序号小于截止日期并且未被填充的空格
代码长度和检验的复杂度完全不是一个数量级的。。。
这种思路最好的地方就是它先放进去的一定是最优的选择
所以你就不用想着再去替换他
我的最后一步是选择已经占了坑的元素中小的再去替换出来
这其实问题是很多的。
唉,自己依旧行走在弱渣的道路上。
不过相信自己会有发光的那一天。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct Work
{
int deadline;
int score;
}x[1002];//结构体数组
bool cmp(Work a,Work b)
{
if(a.score==b.score)
return a.deadline<b.deadline;
return a.score>b.score;
}
int main()
{
int t,n,i,j,sum;
bool a[10002];
cin>>t;
while(t--)
{
sum=0;
cin>>n;
for(i=0;i<n;++i)
scanf("%d",&x[i].deadline);
for(i=0;i<n;++i)
scanf("%d",&x[i].score);
sort(x,x+n,cmp);//根据cmp去进行排序
memset(a,0,sizeof(a));
/*核心代码*/
/*因为已经排过了序,所以先放进去的必然已经是最优的选择了,即分数最大并且截止日期小*/
for(i=0;i<n;++i)
if(!a[x[i].deadline])
{
a[x[i].deadline]=true;
continue;
}
else
{
for(j=x[i].deadline-1;j>=1;--j)
if(!a[j])
{
a[j]=true;
break;
}//若某截止日期没有安排,则将来得及的作业放进去
if(j==0)
sum+=x[i].score;
}
printf("%d\n",sum);
}
return 0;
}