11.19与11.20笔记
Problem - A - Codeforces
类似合并石子,但是合并的代价是\(\max(x,y)\)
对复杂度要求高。
因为每个元素只可能比之前更大,我们最小的数两边的数提前被取一定更优。
int n,pre[N],nxt[N];
struct node{
int key,pos;
}a[N];
int b[N];
inline bool cmp(node x,node y){
return x.key<y.key;
}
inline void clear(){
}
inline void solve(){
cin>>n;
up(i,1,n){
a[i]={read(),i};
b[i]=a[i].key;
pre[i]=i-1;
nxt[i]=i+1;
}
pre[1]=n;nxt[n]=1;
sort(a+1,a+1+n,cmp);
int ans=0;
up(i,1,n-1){
ans+=min(b[pre[a[i].pos]],b[nxt[a[i].pos]]);
nxt[pre[a[i].pos]]=nxt[a[i].pos];
pre[nxt[a[i].pos]]=pre[a[i].pos];
}
cout<<ans<<endl;
}
signed main(){
int T;
cin>>T;
while(T--){
clear();
solve();
}
return 0;
}
Problem - B - Codeforces
很难绷的一道题
让你计算多集合的数量。
首先,很明显的一点。这道题和数无关,只和数的数量有关。
比如 1 1 1 1 2 2 2 3 3 4和2 2 2 2 3 3 3 4 4 1 等价。
然后,我们可以这么依次对每个数进行处理。我们考虑每个数是作为特征数还是非特征数。
那么特征数会覆盖掉非特征数。
我们可以 一个一个数的往下递推。
比如我们看1,可以先分为特证数和非特征数。
如
1 1
1 1
我们考虑先不分组,那么1的分配有5种
但是很容易发现,如果我们把1全放在特证数上。
1111,我们这种情况加上分组则可以为s提供1的各种数量(0除外),而且这样的话,为之后的数提供了更多隐藏的位置,更优。
所以每次我们都只用考虑(0,cnt)和(cnt,0)的情况。
然后就可以考虑背包。
int n,a[N],cnt[N],maxl,f[N];
inline void clear(){
up(i,1,n)a[i]=0;
up(i,1,n)f[i]=0;
maxl=0;
up(i,1,n)cnt[i]=0;
}
signed main(){
int T;
cin>>T;
while(T--){
clear();
cin>>n;
up(i,1,n){
cin>>a[i];
cnt[a[i]]++;
maxl=max(maxl,cnt[a[i]]);
}
f[0]=1;
up(i,1,n){
if(cnt[i]){
dn(j,n,cnt[i]){
f[j]=(f[j]+cnt[i]*f[j-cnt[i]])%mod;
}
}
}
int ans=0;
for(int i=maxl;i<=n;i++)ans=(ans+f[i])%mod;
cout<<ans<<endl;
}
return 0;
}

浙公网安备 33010602011771号