P10156(dp思想)
1.CF1656E(构造思想)2.P10178(构造思想)3.P10179(构造思想+实现)4.P3963 (平衡树思想)
5.P10156(dp思想)
6.P3939 (ds实现)7.CF776D(并查集思想)8.CF243A (拆位思想)9.ABC283E (dp思想)10.AT_joi2015ho_b (dp思想)11.P9588 (ds思想)12.CF482B (拆位思想+实现)13.U332154 carbon 题解(期望)14.U329011 trie pi 题解15.[ARC128D](计数dp)16.P1081 (倍增+代码实现技巧)17.CF1537D (博弈论+找规律)18.CF1557D (dx)(dp技巧)19.P3165/P2596(文艺平衡树套路)20.吉司机大杂烩21.ARC149C (构造)22.CF19D(树套树)23.网络流大杂烩24.U417376题解25.CF1748E(笛卡尔树)26.[CERC2019] Be Geeks!27.「Cfz Round 2」Binary28.CF1833G29.P1028230.CF1939C31.2024省选OIFC模拟T132.P140733.P10218 魔法手杖34.P165335.取模二题36.CF1699C37.ABC35238.P6627 [省选联考 2020 B 卷] 幸运数字39.P6619 [省选联考 2020 A/B 卷] 冰火战士40.2024PKUSC游记难度2
也是比较有意思的一道题。首先发现每个小团体独立,所以对于每个小团体分开直接暴力dp,dp[i][j]表示当前小团体做到第i人,走了j人,然后O(n)转移,加上部分分喜提50pts。为什么要O(n)转移呢,因为我要枚举匹配的两个人然后算贡献。但是对于这种带绝对值的贡献,我们一般都要把绝对值拆掉。拆的方式有两种,一种是像这个和这个一样进行分类讨论,还有就是像这个可以用一些特殊的做法保证绝对值内部的正负性从而消掉绝对值。
我们发现绝对值的正负只和i,j的相对位置有关,我们只需保证i<j或i>j也就是正着做或反着做,我选择正着做,绝对值处理完了,发现还是要O(n)转移怎么办。我们把式子拆开,发现i,j没关系了,自然想到dp[i][j][0/1],表示前i个人走j个人,是否有剩的。代码写起来不难。
#include<bits/stdc++.h>
using namespace std;
long long n,m,kk,x,y,a[5005],b[5005][5005],len[5005];
long long minn[5005],dp1[5005][5005],dp[5005][5005][2];//前i个人走j个人,有剩的
int main(){
ios::sync_with_stdio(false);cin.tie(0);
memset(dp,0x3f,sizeof(dp));
memset(dp1,0x3f,sizeof(dp1));
dp1[0][0]=0;
cin>>n>>m>>kk>>x;
m=n-m;
if(m%2==1) m++;
for(long long i=1;i<=n;i++){
cin>>a[i];
}for(long long i=1;i<=n;i++){
cin>>y;
len[y]++;
b[y][len[y]]=i;
}
for(long long i=1;i<=kk;i++){
if(len[i]>=2){
for(int j=0;j<=len[i];j++){
for(int k=0;k<=len[i];k++){
dp[j][k][0]=dp[j][k][1]=1e16;
}
}
dp[1][0][1]=a[b[i][1]]-x*b[i][1];
dp[1][0][0]=0;
for(int j=2;j<=len[i];j++){
dp[j][0][0]=dp[j-1][0][0];
dp[j][0][1]=min(dp[j-1][0][1],a[b[i][j]]-x*b[i][j]);
for(int k=2;k<=len[i];k+=2){
dp[j][k][0]=min(dp[j-1][k-2][1]+a[b[i][j]]+x*b[i][j],dp[j-1][k][0]);
dp[j][k][1]=min(dp[j-1][k][1],dp[j-1][k][0]+a[b[i][j]]-x*b[i][j]);
}
}
memset(minn,0x3f,sizeof(minn));
for(long long j=2;j<=len[i];j+=2){
for(long long k=j;k<=len[i];k++){
minn[j]=min(minn[j],dp[k][j][0]);
}
}
minn[0]=0;
dp1[i][0]=0;
for(long long j=0;j<=len[i];j+=2){
for(long long k=j;k<=m;k+=2){
dp1[i][k]=min(dp1[i][k],dp1[i-1][k-j]+minn[j]);
}
}
}else{
for(long long j=0;j<=m;j+=2){
dp1[i][j]=dp1[i-1][j];
}
}
}
if(dp1[kk][m]>1e14) cout<<"Impossible"<<endl;
else cout<<dp1[kk][m];
return 0;
}/*
7
5 3 2 1 6 4 7
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?