リンク:
https://leetcode.cn/problems/longest-subsequence-with-limited-sum/
タイトルの意味:
配列 nums と配列クエリは、クエリ内の数値 temp ごとに答え ans を提供します。ans の値はnums 内で最長であり、サブシーケンスの要素と長さはtemp 以下です。
サブシーケンスの概念:サブシーケンスは、残りの要素の順序を変更せずに、配列から一部の要素を削除する (または削除しない) ことによって得られる配列です。
ほどく:
貪欲な思考、接頭辞、
temp 以下の最長のサブシーケンスを見つけたいので、temp を超えるまで毎回最小の数値を加算すれば十分であることがわかります。
次に、最初に数値をソートし、次にプレフィックスと合計をソートすると、長さが i のときのサブシーケンスの最小値を取得できます。
それから、直接(1K*1K)トラバースすることは可能かもしれないと思いますが、それでも2つの点を書きました
私の2得点はディフェンスQWQに頼るしかないとしか言いようがない
実際のコード:
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int Nmax=1E3+7;
int sz[Nmax];
int Binary_Search(int l,int r,int mao)
{
int mid=(l+r)/2;
//cout<<"BS:"<<l<<" "<<r<<" "<<mid<<" "<<sz[mid]<<" "<<sz[l]<<"&"<<sz[r]<<endl;
if(r==l+1)//特判情况1
{
if(sz[r]<=mao) return r+1;
else if(sz[l]<=mao) return l+1;
else return l;
}
if(l==r)//特判情况2
{
if(sz[l]<=mao) return l+1;
else return l;
}
if(sz[mid]==mao) return mid+1;
if(sz[mid]<mao) return Binary_Search(mid,r,mao);
if(sz[mid]>mao) return Binary_Search(l,mid-1,mao);
return 0;
}
vector<int> solve(vector<int>& nums, vector<int>& queries)
{
vector<int>ans;
sort(nums.begin(),nums.end());
int lg_nums=nums.size(),lg_q=queries.size();
sz[0]=nums[0];
for(int i=1;i<lg_nums;i++) sz[i]=sz[i-1]+nums[i];//前缀
for(auto i:queries)
{
int temp=Binary_Search(0,lg_nums-1,i);
//cout<<i<<"-temp:"<<temp<<endl;
ans.push_back(temp);
}
return ans;
}
int main()
{
vector<int>nums,queries;
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++)
{
int temp;cin>>temp;
nums.push_back(temp);
}
for(int i=1;i<=m;i++)
{
int temp;cin>>temp;
queries.push_back(temp);
}
vector<int>ans=solve(nums,queries);
for(auto i:ans)
{
cout<<" "<<i;
}
cout<<endl;
}
制限:
n == nums.length
m == queries.length
1 <= n, m <= 1000
1 <= nums[i], queries[i] <= 10^6