18.8.30考试总结

这道题明明很简单!!!!! 但是由于我的智商和wans_的智商打架了 受了重伤 所以就变笨了

看到题目之后很容易发现两个性质

1.不管这些球球怎么弹弹弹 他们的相对位置是不会变的

2.两个球碰撞之后互相反向 但是实际上相当于他们互相继承了对方的意志 去完成对方的使命

也就是说如果某一个球一开始在a位置向左走 a秒之后就会有一个球从左端点掉下去 不管这个是不是原来的球球

所以可以得到球从左端点和右端点掉下去的时间 再根据他们的相对位置排回原来的标号

代码

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5;
int n,l,a[N],c1[N],c2[N],tot1,tot2,d[N];

int main( ) {
    
    freopen("ant.in","r",stdin);
    freopen("ant.out","w",stdout);
    scanf("%d%d",& l,& n);
    for(int i = 1;i <= n;i ++) scanf("%d",& a[i]);
    for(int i = 1;i <= n;i ++) {
        scanf("%d",& d[i]);
        if(d[i] == 0) {
            c1[++ tot1] = a[i];
        }
        else c2[++ tot2] = l - a[i];
    }
    sort(c1 + 1,c1 + tot1 + 1);
    sort(c2 + 1,c2 + tot2 + 1);
    for(int i = 1;i <= tot1;i ++) printf("%d.00 ",c1[i]);
    for(int i = tot2;i >= 1;i --) printf("%d.00 ",c2[i]);
}

这道题就是一道原题嘛 之前我都有写过总结应该

因为想要操作次数最少 也就是剩余的花朵最多

 

$ dp[i] $ 表示选择1 ~ i的区间所能够剩余的最多单调不降的花朵的数量

然后用辅助数组 $ h[i] $ 表示 $ dp[i ]$ 对应的最后一个的高度 转移是很好理解的 就是枚举决策点 后面一段全部合并来转移dp

乱搞搞就可以了

代码

#include <bits/stdc++.h>
using namespace std;

const int N = 5 * 1e3 + 5;
int dp[N],h[N],sum[N],a[N],n;

int main( ) {
    
    freopen("flower.in","r",stdin);
    freopen("flower.out","w",stdout);
    scanf("%d",& n);
    for(int i = 1;i <= n;i ++) {
        scanf("%d",& a[i]);
        sum[i] = sum[i - 1] + a[i];
    }
    for(int i = 1;i <= n;i ++) {
        for(int j = 1;j <= i;j ++) {
            int s = sum[i] - sum[j - 1];
            if(s >= h[j - 1] && dp[i] < dp[j - 1] + 1) {
                dp[i] = dp[j - 1] + 1;
                h[i] = s;
            }
            else if(s >= h[j - 1] && dp[i] == dp[j - 1] + 1) {
                h[i] = min(h[i],s);
            }
        }
    }
    printf("%d",n - dp[n]);
}

这道题可以说是很简单了 二分答案 + 贪心check 然后就完了

其实可以O(n)check的 思路跟我是一样的 都是差分 但是我爱树状数组...!!就这样

代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N = 1e5 + 3;
int n,k;
ll a[N],del[2 * N],t;

ll lowbit(ll a) {
    
    return a & (-a);
}

ll query(int pos) {
    
    ll ans = 0;
    while(pos >= 1) {
        ans += del[pos];
        pos -= lowbit(pos);
    }
    return ans;
}

void add(int pos,ll d) {
    
    while(pos <= n) {
        del[pos] += d;
        pos += lowbit(pos);
    }
}

bool check(ll len) {
    
    ll c = t;
    memset(del,0,sizeof(del));
    for(int i = 1;i <= n;i ++) {
        ll delt = query(i);
        if(a[i] + delt >= len) continue;
        else {
            ll dd = len - a[i] - delt;
            c -= dd;
            if(c < 0) return false;
            add(i,dd); add(i + k,-dd);
        }
    }
    return true;
}

void solve( ) {
    
    ll l = 1,r = 2 * 1e9;
    ll ans = 0;
    while(l <= r) {
        ll mid = (l + r) >> 1;
        if(check(mid)) ans = mid,l = mid + 1;
        else r = mid - 1;
    }
    printf("%I64d",ans);
}

int main( ) {
    
    freopen("watering.in","r",stdin);
    freopen("watering.out","w",stdout);
    scanf("%d%d%I64d",& n,& k,& t);
    for(int i = 1;i <= n;i ++) scanf("%I64d",& a[i]);
    solve( );
}

猜你喜欢

转载自www.cnblogs.com/Rubenisveryhandsome/p/9560285.html