2020.4.12 bytes written test questions B dp D monotonic stack

A Simple exchange

Water question. .

B--fold wooden stick

 

The solution comes from group friends

f [i] [j]: The i-th wooden stick is split into a maximum value of j so that the minimum number of
splits satisfying the previous conditions is greedy. A minimum value of the wooden stick X and the number of times S
f [i] [j ] = max (f [i-1] [k] + s) k <= x

In fact, the maximum value of each wooden stick a [i] enumeration is len (the rightmost is len) and the leftmost: a [i]% len Calculate the minimum split method: s = a [i] / len + ((a [i ]% len == 0)? 0: 1) -1 

According to each position, the leftmost number of len is either a [i]% len or len. How to calculate the legal maximum value on the leftmost? The average number of pos + 1 is a [i]. k = a [i] / (pos + 1)

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

LL a[3005], f[3005][3005];

int main() {

    int n; scanf("%d", &n);
    for(int i=1; i<=n; i++){
        scanf("%lld", &a[i]);
    }
    memset(f, 7, sizeof(f));
    for(int i=0; i<3005; i++) f[0][i]=0;

    for(int i=1; i<=n; i++){
        for(int len=1; len<3005; len++){
            if(len>a[i]){
                f[i][len]=f[i][len-1];
                continue;
            }
            LL pos=a[i]/len+((a[i]%len==0)?0:1)-1;//按照mi len len len 切的次数pos
            LL mi=((a[i]%len==0)?len:(a[i]%len));
            //pos*len+mi==a[i]
            LL x=(pos*len+mi)/(pos+1);//切pos刀有pos+1个位置,a[i]平均分给pos+1个位置就是最大合法的值x

            //printf("mi:%lld x:%lld\n",mi,x);
            f[i][len]=f[i-1][x]+pos;
            f[i][len]=min(f[i][len], f[i][len-1]);
            //cout<<i<<" "<<len<<" "<<f[i][len]<<endl;
        }
    }
    LL ans=1<<30;
    for(int i=1; i<=a[n]; i++){
        ans=min(ans, f[n][i]);
    }
    printf("%lld\n", ans);

    return 0;
}
/*
5
3 5 13 9 12
ans:1

5
5 4 3 2 1
ans:
*/

C--Coupon

To sort a, b [i] can be divided into two in a.

D--Stand high and look far

Classic monotone stack question

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=1e6+10;
int a[N],ans[N],n,m,l[N],r[N];
int main()
{
   int _;cin>>_;while(_--)
   {
       scanf("%d",&n);
       rep(i,1,n) scanf("%d",&a[i]);
       stack<int>sta;
       rep(i,1,n) l[i]=r[i]=i;
       for(int i=1;i<=n;++i){
            if(sta.size()==0) sta.push(i);
            else{
                while(sta.size()&&a[i]>=a[sta.top()]) {
                    sta.pop();
                }
                if(sta.size()) l[i]=sta.top()+1;
                else l[i]=1;
                sta.push(i);
            }
       }
       while(sta.size()) sta.pop();

       for(int i=n;i;--i){
            if(sta.size()==0) sta.push(i);
            else{
                while(sta.size()&&a[i]>=a[sta.top()]) {
                    sta.pop();
                }
                if(sta.size()) {
                    r[i]=sta.top()-1;

                }
                else r[i]=n;

                sta.push(i);
            }
       }
       rep(i,1,n)
       {
           printf("%d ",r[i]-l[i]);
       }
       puts("");


   }
}

 

Published 519 original articles · praised 69 · 50,000+ views

Guess you like

Origin blog.csdn.net/qq_41286356/article/details/105486761