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 <= xIn 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("");
}
}