自己看过了,找同学看过了,还重构了一遍,就是没发现有什么问题,求助。
#include<bits/stdc++.h>
using namespace std;
#define N 100003
#define LL long long
#define INF 0x3f3f3f3f
int T,n,m,ed[N],asl[N];
LL a[N],dp[203];
struct plan{
int e,p,id;
LL t;
}p[N];
struct node{
int nw,ls,ln;
}pr[203];
bool cmp(plan a,plan b){
if(a.e!=b.e) return a.e<b.e;
return a.t<b.t;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%lld",&a[i]);
for(int i=1;i<=m;++i)
scanf("%d%lld%d",&p[i].e,&p[i].t,&p[i].p),
p[i].id=i;
p[m+1]={0,0,0,0};
sort(p+1,p+m+1,cmp);
for(int i=1;i<=m;++i) //分出所有任务
if(p[i].e!=p[i+1].e) ed[p[i].e]=i;
LL sm=0;
int nw=1,fl=0,tot=0;
for(int i=1;i<=n;++i){
LL ans=INF;
int ni=0,nj=0;
memset(dp,0x3f,sizeof dp);
dp[0]=0;
for(;nw<=ed[i];++nw){
int pp=p[nw].p;
for(int j=200;j>=pp;--j){ //一个平凡的背包记录方案
if(dp[j-pp]+p[nw].t<dp[j])
dp[j]=dp[j-pp]+p[nw].t,
pr[j]={nw,j-pp,pr[j-pp].nw};
if(j>=100&&dp[j]<ans) //如果当前在100及以上那么记录答案
ans=dp[j],nj=j,ni=nw;
}
}
sm+=ans;
if(sm>a[i]){fl=1;break;} //若不能按时完成则-1
while(nj) //输出方案,之前记的ln用来避免重复
asl[++tot]=p[ni].id,
ni=pr[nj].ln,nj=pr[nj].ls;
}
if(fl){puts("-1");continue;}
printf("%d\n",tot);
for(int i=1;i<tot;++i)
printf("%d ",asl[i]);
printf("%d\n",asl[tot]);
}
return 0;
}
这份代码在第 3 个点的第 2169 个数据,第 17 个点的第 3953,6237 个数据显示没有按时完成所有任务,在第 17 个点的第 2063,3407,5848 个数据显示我使用的操作数多于他给出的 m。经我测试这几个点答案都是 -1,也就是代码里判无解出现了问题。
还有第 20 个点的第 183 个数据显示我的操作没有完成所有任务,并且这个点答案并不是 -1,但我据代码找不到 dp 部分有什么问题,猜测是输出方案出错。