EXAM-2018-7-22
EXAM-2018-7-22
B
从大到小排列
暴力剪枝
E
树状数组+思维
对于数组中的任意一个数,有多少数原先在他前面的到了后面,就是最后的答案。最后要注意max(1,ans);
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int c[maxn];
struct node
{
int val;
int num;
}s[maxn];
bool cmp(node a,node b)
{
if(a.val==b.val) return a.num<b.num;
else return a.val<b.val;
}
int lowbit(int x){
return -x&x;
}
void update(int pos, int val){
for(int i = pos; i < maxn; i += lowbit(i)){
c[i] += val;
}
}
int query(int pos){
int res = 0;
for(int i = pos; i > 0; i -= lowbit(i)){
res += c[i];
}
return res;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>s[i].val;
s[i].num=i;
}
sort(s+1,s+n+1,cmp);
int ans=0;
for(int i=1;i<=n;i++){
update(s[i].num,1);
ans=max(ans,i-query(i));
}
cout<<max(ans,1)<<endl;
return 0;
}
D
本题知识点:01分数规划
sum(ti)/sum(wi) = x.则有sum(ti) = sum(wi)x. 进一步得出sum(ti)-sum(wi)x = 0. 展开后利用加法交换律得到sum(ti-wi*x) = 0
再者0-1背包的过程中,由于背包的容量没有上限,所以背包的权值可以是在0到W+wi,所以二维dp维护的过程中可以将j-wi变成j+wi。,然后再进行背包。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct node {
ll t,w;
}a[2560];
ll n,w;
bool judge(ll x){
ll dp[2560];
memset(dp,128,sizeof(dp));
dp[0]=0;
for(ll i=0;i<n;i++){
for(ll j=w;j>=0;j--){
int t=min(w,a[i].w+j);
dp[t]=max(dp[t],dp[j]+a[i].t-x*a[i].w);
}
}
if(dp[w]>=0) return true;
return false;
}
inline void init()
{
for(int i=0;i<n;i++){
scanf("%lld%lld",&a[i].w,&a[i].t);
a[i].t*=1000;//好处理
}
}
int main(){
scanf("%lld%lld",&n,&w);
init();
ll L=0,R=10000005,mid;
ll ans=0;
while(L<=R){//二分模板
mid=(L+R)/2;
if(judge(mid)){
ans=mid;
L=mid+1;
}
else{
R=mid-1;
}
}
printf("%lld\n",ans);
}
不要忘记努力,不要辜负自己
欢迎指正 QQ:1468580561

浙公网安备 33010602011771号