01二重退背包+组合数学——cf1111d
退背包进阶,还是挺难想的
/*
dp1[k]表示取到体积k的方案数
dp2[i][j][k]表示左侧必选ij的情况下,取到体积k的方案数
dp2[i][j][k]=dp1[k]-左侧不选ij的方案数
但是这样比较难搞,我们把状态转换一下,dp2[i][j][k]表示左侧不选i,j,取到k的方案数
这样要两层退背包来解决
状态前两维可以直接压缩,用ans[i][j]来保存答案,复杂度O(52*52*n)
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
#define ll long long
#define mod 1000000007
ll f[maxn],inv[maxn],invf[maxn];
void init(){
f[]=inv[]=invf[]=invf[]=;
for(int i=;i<maxn;i++)
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
for(int i=;i<maxn;i++){
f[i]=f[i-]*i%mod;
invf[i]=invf[i-]*inv[i]%mod;
}
} char s[maxn];
ll cnt[],n,C;
ll dp1[maxn],dp2[maxn],dp3[maxn],ans[][];
void work(){
//先处理背包
dp1[]=;
for(int i=;i<;i++)
if(cnt[i])
for(int j=n/;j>=cnt[i];j--)
dp1[j]=(dp1[j]+dp1[j-cnt[i]])%mod;
for(int i=;i<;i++)
if(cnt[i]){
//先退去一层:没有底i个物品时的状态dp2
memset(dp2,,sizeof dp2);
for(int k=;k<=n/;k++)
if(k<cnt[i]) dp2[k]=dp1[k];
else dp2[k]=(dp1[k]-dp2[k-cnt[i]]+mod)%mod;
ans[i][i]=dp2[n/]; for(int j=;j<;j++)
if(j!=i && cnt[j]){
//再退一层背包
memset(dp3,,sizeof dp3);
for(int k=;k<=n/;k++)
if(k<cnt[j])dp3[k]=dp2[k];
else dp3[k]=(dp2[k]-dp3[k-cnt[j]]+mod)%mod;
ans[i][j]=ans[j][i]=dp3[n/];
}
}
} int main(){
init();
scanf("%s",s);
n=strlen(s);
for(int i=;i<n;i++){
if(s[i]<='Z' && s[i]>='A')
cnt[s[i]-'A']++;
else cnt[s[i]-'a'+]++;
} C=*f[n/]*f[n/]%mod;
for(int i=;i<;i++)
C=C*invf[cnt[i]]%mod; work(); int q;cin>>q;
while(q--){
char a,b;int c,d;
scanf("%d %d",&c,&d);
a=s[c-],b=s[d-];
if(a<='Z' && a>='A')
c=a-'A';
else c=a-'a'+;
if(b<='Z' && b>='A')
d=b-'A';
else d=b-'a'+; cout<<ans[c][d]*C%mod<<'\n';
}
}
01二重退背包+组合数学——cf1111d的更多相关文章
- 【Codeforces1111D_CF1111D】Destroy the Colony(退背包_组合数学)
题目: Codeforces1111D 翻译: [已提交至洛谷CF1111D] 有一个恶棍的聚居地由几个排成一排的洞穴组成,每一个洞穴恰好住着一个恶棍. 每种聚居地的分配方案可以记作一个长为偶数的字符 ...
- 01退背包——bzoj2287
退背包就是限制某一件物品不可取的方案数 先做出无限制的方案数,然后对于当前不可取的物品,dp2[j]表示不取改物品情况下,取得体积为j的方案数 有状态方程 dp2[j]=dp1[j]-dp2[j-w[ ...
- 01二维背包+bitset优化——hdu5890
口胡一种别的解法: 三重退背包,g1[j]k]表示不选x的选了j件物品,体积为k的方案数,g[0][0] = 1 , g1[j][k]=dp[j][k]-g1[j-1][k-a[x]] 然后按这样再退 ...
- luogu 4377 Talent show 01分数规划+背包dp
01分数规划+背包dp 将分式下面的部分向右边挪过去,通过二分答案验证, 注意二分答案中如果验证的mid是int那么l=mid+1,r=mid-1,double类型中r=mid,l=mid; 背包dp ...
- BZOJ.2287.[POJ Challenge]消失之物(退背包)
BZOJ 洛谷 退背包.和原DP的递推一样,再减去一次递推就行了. f[i][j] = f[i-1][j-w[i]] + f[i-1][j] f[i-1][j] = f[i][j] - f[i-1][ ...
- Codeforces 1111D(退背包、排列组合)
要点 优质题解 因为只有某type坏人全部分布在同一撇时,才能一次消灭.所以题目安排完毕后一定是type(x)和type(y)占一半,其余占另一半. 实际情况只有52*52种,则预处理答案 枚举某两种 ...
- Codeforces1111D Destroy the Colony 退背包+组合数
Codeforces1111D 退背包+组合数 D. Destroy the Colony Description: There is a colony of villains with severa ...
- 01二维背包——poj2576
/* 要求把a数组分成两个集合,两个集合人数最多差1,并且元素之和的差尽可能小 那只要把所有可行的列出来即可 01二维背包,即体积是个二维数据,那么我们的背包状态也应该设为二维 dp[j][k]设为 ...
- Codeforces 1111D Destroy the Colony 退背包 (看题解)
第一次知道这种背包还能退的.... 我们用dp[ i ]表示选取若干个物品重量到达 i 的方案数. 如果我们g[ i ]表示不用第 x 个物品的, 然后选若干其他的物品到达 i 的方案数. if(i ...
随机推荐
- 关于C#中Convert.ToInt32()是干什么用的
并非每个对象都可以直接转换为int.例如,以下内容将无法编译: string Maomao = "100"; int i = (int)Maomao; 因为string无法隐式转换 ...
- spring data jpa 配置文件1
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...
- BZOJ 2326: [HNOI2011]数学作业(矩阵乘法)
传送门 解题思路 NOIp前看到的一道题,当时想了很久没想出来,NOIp后拿出来看竟然想出来了.注意到有递推\(f[i]=f[i-1]*poww[i]+i\),\(f[i]\)表示\(1-i\)连接起 ...
- C语言新手写扫雷攻略3
界面绘制好后,雷数也布置了,接下来就是游戏的运行过程了,今天先不说具体过程,再来看看需要用到的辅助函数 先是简单的画红旗,鼠标右键的功能是画红旗,至此我们都是在使用函数自己绘图,效率是低,但有助于理解 ...
- C++的ofstream与ifstream使用
基本理解: ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间; 在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的 ...
- 7、Appium常用API
嗯,官网已经介绍的很全了.会选几个常用API后期整理. Appium常用API地址:http://appium.io/docs/cn/writing-running-appium/appium-bin ...
- C++子类父类构造函数的关系
在C++中子类继承和调用父类的构造函数方法 构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法).因此,在创建子类对象 ...
- 20140702 赋值构造函数的形参为什么一定用引用。string类的赋值运算函数的注意点
1.复制构造函数为什么一定要用引用,而不是用值 类名::复制构造函数(类名&引用名) 传递引用,可以避免复制,如果一个数据相当大的化,进行复制会浪费很多时间的. 类名::复制构造函数(类名 变 ...
- There was an unexpected error (type=Method Not Allowed, status=405). Request method 'POST' not supported
背景:点击提交按钮ajax请求接口时,报出错误[ Whitelabel Error Page This application has no explicit mapping for /error, ...
- JUC源码分析-集合篇(十)LinkedTransferQueue
JUC源码分析-集合篇(十)LinkedTransferQueue LinkedTransferQueue(LTQ) 相比 BlockingQueue 更进一步,生产者会一直阻塞直到所添加到队列的元素 ...