[csa round#1]Number Elimination——动态规划+计数
题目大意:
你有个方块排成一排,每个方块有一个权值,你每次可以选择一个二元组,并消除x和y中权值较小的那个方块,如果二者权值相同则消除标号较小的那个,产生的费用。你每次选择的二元组中不能选择已经被消除的方块。最后这一排方块只会剩下一个,游戏目标是使费用最少。
求可以使费用最小的方案数。
思路:
为了使费用最小,可以发现相同的数一定是要在一起消,直到只剩一个。
同时对于不同的数之间,我们要消除一个数的话,这个数必定只剩下一个,并且比这个数小的数都要在之前消完。
不同的种类一定是从小到大的顺序消完,于是我们设dp[i]为前i个种类消完的方案数,每一次将一个种类添加进去来转移。
这里需要预处理一个种类自身消除的方案数(i为集合大小)。
于是在dp[i]的时候枚举第i个种类的物品在i-1种最后一个消完之前消完的数量j,用隔板法来计算前j个放置的位置,可得dp方程为:
直接转移即可。
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a,i##_end_=b;i<=i##_end_;++i)
#define DREP(i,a,b) for(int i=a,i##_end_=b;i>=i##_end_;--i)
#define debug(x) cout<<#x<<"="<<x<<endl
typedef long long ll;
using namespace std;
void File(){
freopen("out.in","r",stdin);
freopen("out.out","w",stdout);
}
template<typename T>void read(T &_){
T __=0,mul=1; char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')mul=-1;
ch=getchar();
}
while(isdigit(ch))__=(__<<1)+(__<<3)+(ch^'0'),ch=getchar();
_=__*mul;
}
const int maxn=1e5+10;
const ll mod=1e9+7;
int n,a[maxn],b[maxn],tot,cnt[maxn];
ll fac[maxn],ifac[maxn],f[maxn],dp[maxn],sum[maxn];
ll qpow(ll x,ll y){
ll ret=1; x%=mod;
while(y){
if(y&1)ret=ret*x%mod;
x=x*x%mod;
y>>=1;
}
return ret;
}
ll C(ll x,ll y){return fac[x]*ifac[y]%mod*ifac[x-y]%mod;}
int main(){
// File();
read(n);
REP(i,1,n)read(a[i]),b[++tot]=a[i];
sort(b+1,b+tot+1);
tot=unique(b+1,b+tot+1)-b-1;
REP(i,1,n)a[i]=lower_bound(b+1,b+tot+1,a[i])-b;
fac[0]=1;
REP(i,1,n)fac[i]=fac[i-1]*i%mod;
ifac[n]=qpow(fac[n],mod-2);
DREP(i,n-1,0)ifac[i]=ifac[i+1]*(i+1)%mod;
REP(i,1,n)++cnt[a[i]];
f[0]=1;
ll inv2=qpow(2,mod-2);
REP(i,1,n)f[i]=f[i-1]*i%mod*(i+1)%mod*inv2%mod;
dp[1]=f[cnt[1]-1];
REP(i,2,tot){
sum[i-1]=sum[i-2]+cnt[i-1];
REP(j,0,cnt[i]-1)
dp[i]=(dp[i]+dp[i-1]*C(sum[i-1]+j-1,j)%mod*(cnt[i]-j)%mod)%mod;
dp[i]=dp[i]*f[cnt[i]-1]%mod;
}
printf("%lld\n",dp[tot]);
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!