帮忙看看哪里错了。。谢谢
我用dp加单调数组做的;
单调数组q[i]记录的是从i往前到j(Sigema(a[i].v+..+a[j].v)恰好大于等于m)之间最大的那个数的序号
dp转移方程 dp[i]=max(dp[i-1],dp[last[i]-1]+a[q[head]].v);
#include\"stdio.h\"
#include\"string.h\"
#define N 50005
struct in{
	int p,v;
}a[N];
int last[N];
double sum[N];
int q[N];
double dp[N];
int main()
{
	int i,j,k,t;
	double now;
	int ii,jj,kk;
	int head,tail;
	double s;
	int n,m;
	scanf(\"%d\",&t);
	while(t--)
	{
		scanf(\"%d%d\",&n,&m);
		for(i=1;i<=n;i++)
			scanf(\"%d%d\",&a[i].p,&a[i].v);
		s=0;
		for(i=1;i<=n;i++)
		{
			s=s+a[i].p;
			if(s>=m)
				break;
		}
		if(i>n)
		{
			printf(\"0\\n\"); continue;
		}
		memset(dp,0,sizeof(dp));
		head=tail=0; q[0]=1;
		last[i]=1; sum[i]=s;
		for(j=2;j<=i;j++)
		{
			while(tail>=head&&a[j].v>=a[q[tail]].v)
			{
				tail--;
			}
			q[++tail]=j;
		}
		dp[i]=a[q[head]].v;
		for(j=i+1;j<=n;j++)
		{
			while(tail>=head&&a[j].v>=a[q[tail]].v)
			{
				tail--;
			}
			q[++tail]=j;
			if(a[j].p>=m)
			{
				last[j]=j;
				sum[j]=a[j].p;
			}
			else
			{
				now=sum[j-1]+a[j].p;
				for(k=last[j-1];;k++)
				{
					now=now-a[k].p;
					if(now<m)
						break;
				}
				last[j]=k;
				sum[j]=now+a[k].p;
			}
			while(q[head]<last[j])
				++head;
			dp[j]=dp[j-1];
			if(a[q[head]].v+dp[last[j]-1]>dp[j])
				dp[j]=dp[last[j]-1]+a[q[head]].v;
		}
		printf(\"%.0lf\\n\",dp[n]);
	}
}
© 2015 HUST ACMICPC TEAM. All Right Reserved.