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);
}

地址 EXAM-2018-7-22

posted @ 2018-07-28 22:48  house_cat  阅读(121)  评论(0)    收藏  举报