转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
259A:每一行,wbwbwbwb,bwbwbwbw这两种情况是合法的
259B:SB了半天,题目只说了对角线是未知的,随意瞎搞吧,不知道什么好办法
258A:被cha一次,注意全为1的情况,就是从高位判断,去掉第一个0,如果全为1,则随便去掉一位
258B:数位DP+DFS
数位DP处理出1---n含有i个lucky number的数有多少个
然后DFS每一个候选者选的种类,直接计数
一直不敢写,对于数位DP,没有把握,不过还好最后过了
LL dp[15][15];
void DP(){
mem(dp,0);
dp[0][0]=1;
for(int i=0;i<10;i++){
for(int j=0;j<=i;j++){
if(dp[i][j]==0) continue;
dp[i+1][j+1]+=dp[i][j]*2;
dp[i+1][j]+=dp[i][j]*8;
}
}
}
int slove(int n,int m){
int bit[20],len=0;
while(n){
bit[len++]=n%10;
n/=10;
}
int cnt=0,tot=0;
for(int i=len-1;i>=0;i--){
for(int j=0;j<bit[i];j++){
if(j==4||j==7){
if(tot!=m)
cnt+=dp[i][m-tot-1];
}
else cnt+=dp[i][m-tot];
}
if(bit[i]==4||bit[i]==7) tot++;
if(tot>m) break;
}
if(tot==m) cnt++;
if(m==0) cnt--;
return cnt;
}
int n;
int cnt[10],t[10];
LL ans=0;
void dfs(int idx,int now,int limit,LL ret){
if(idx==6){
ans=(ans+ret)%MOD;
return ;
}
for(int i=0;i<10;i++){
if(i+now>=limit) break;
if(t[i]==0) continue;
t[i]--;
dfs(idx+1,now+i,limit,ret*(t[i]+1)%MOD);
t[i]++;
}
}
int main(){
DP();
while(scanf("%d",&n)!=EOF){
for(int i=0;i<10;i++){
cnt[i]=slove(n,i);
}
ans=0;
for(int i=1;i<10;i++){
if(cnt[i]==0) continue;
memcpy(t,cnt,sizeof(cnt));
t[i]--;
dfs(0,0,i,cnt[i]%MOD);
}
printf("%I64d\n",ans);
}
return 0;
}
258C:枚举lcm,然后找出所有的因子,假设约数个数为m
第一步先处理,肯定至少有一个数要取lcm,那么至少有一个数取lcm,便是所有>=lcm的数,都有m种可能,这样肯定包括没有取到lcm的情况,只要减掉所有数都取<lcm,即m-1种可能的
然后枚举其它因子
int n;
int a[N],c[N];
LL PowMod(LL a,LL b){
LL ret=1;
while(b){
if(b&1)
ret=((LL)ret*a)%MOD;
a=((LL)a*a)%MOD;
b>>=1;
}
return ret;
}
int main(){
while(scanf("%d",&n)!=EOF){
int limit=0;
mem(c,0);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
c[a[i]]++;
limit=max(limit,a[i]);
}
for(int i=N-2;i>=1;i--)
c[i]+=c[i+1];
LL ans=1;
vector<int>v;
for(int i=2;i<=limit;i++){
v.clear();
for(int j=1;j*j<=i;j++){
if(i%j==0){
v.pb(j);
if(j*j!=i)
v.pb(i/j);
}
}
sort(v.begin(),v.end());
int m=v.size();
LL sum=((PowMod((LL)m,(LL)c[v[m-1]])-PowMod((LL)m-1,(LL)c[v[m-1]]))%MOD+MOD)%MOD;
for(int j=0;j<m-1;j++){
sum=(sum*PowMod((LL)j+1,(LL)c[v[j]]-c[v[j+1]]))%MOD;
if(sum<0) test;
}
ans=(ans+sum)%MOD;
}
printf("%I64d\n",ans);
}
return 0;
}
258 D:概率DP
p[i][j]表示a[i]>a[j]的概率
那么初始可以得到
对于某一次操作,需要交换a[u],a[v]
那么可以交换,也可能交换,所以p[u][v]=p[v][u]=0.5。因为交换或者不交换,要么是逆序对,要么不是
那么之后枚举所有的i,i!=x&&i!=y
那么以p[u][i]为例,那么a[u]与a[i]的关系,如果a[u]和a[v]不交换,那么p[u][i]不变,这样的可能为p[u][i]*0.5
如果交换的话,则原来的v变为了u,则p[v][i]*0.5
所以p[u][i]=p[u][i]*0.5+p[v][i]*0.5;
最后叠加就是期望
258E:http://blog.csdn.net/acm_cxlove/article/details/8395747