1475D。電話のクリーニング(2ポイント+プレフィックス合計)

ポータル

ので、双方向b_ibたった111及び2 22 2つのタイプ、1、a 2 a1、a2に分割することを検討してくださいa 1 2つの数字は、対応する組み立てAI a_iををA

a 1 a1 a1里的 a i a_i A b i = 1 b_i=1 b=1、次に1 a11の項目には明らかな長所と短所があります。aia_iA大きければ大きいほど良い

つまり、a 1、a 2 a1、a2a 1 a2按照 a i a_i A最大から最小に並べ替え

列挙型a1 a11取る前に、配列IIをiアイテム

現時点では、2つのポイントを使用して、最小インデックスインデックスをすばやく取得できますi n d e xは、前のインデックスインデックスを削除しますi n d e x biga 2 a22要素

条件を満たしてから、回答を更新してください

dpが機能していないようです(多分それは可能ですか?)...

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 3e5+10;
const int inf = 1e15;
int t,n,m,a[maxn],b[maxn],a1[maxn],a2[maxn],pre[maxn];
bool com(int a,int b){
    
     return a>b; }
signed main()
{
    
    
	int t; cin >> t;
	while( t-- )
	{
    
    
		cin >> n >> m;
		for(int i=1;i<=n;i++)	scanf("%lld",&a[i]);
		for(int i=1;i<=n;i++)	scanf("%lld",&b[i]); 
		a1[0]=a2[0]=0;
		for(int i=1;i<=n;i++)
		{
    
    
			if( b[i]==1 )	a1[++a1[0]] = a[i];
			else	a2[++a2[0]] = a[i];
		}
		sort( a1+1,a1+1+a1[0],com );
		sort( a2+1,a2+1+a2[0],com );
		for(int i=1;i<=a2[0];i++)	pre[i] = pre[i-1]+a2[i];
		//ö��ѡ��s��
		int ans = inf,sum=0;
		for(int i=1;i<=a1[0];i++)
		{
    
    
			sum+=a1[i];
			if( sum>=m ){
    
     ans=min(i,ans); break; }
			int yu = m-sum;
			int index = lower_bound( pre+1,pre+1+a2[0],yu )-pre;
			if( index==a2[0]+1 )	continue;
			ans = min( ans,i+index*2 );
		} 
		int index = lower_bound( pre+1,pre+1+a2[0],m )-pre;
		if( index!=a2[0]+1 )
			ans = min( ans,index*2 );
		if( ans==inf )	cout << -1 << endl;
		else	cout << ans << endl;
	}
}

おすすめ

転載: blog.csdn.net/jziwjxjd/article/details/113156561