11.2 NOIP模拟赛 (morning)
来源:互联网 发布:淘宝烈风自行车怎么样 编辑:程序博客网 时间:2024/06/06 05:34
思路:
明显的DP,所以我考试时用的搜索............100的数据搜到 6*6 就爆了....尴尬 (0.0)还是来讲讲DP吧 这题有3种情况 一是 这列不放炮 二是放一个炮 三是放两个炮(这不废话么.....)那么 我们就开三维数组 f[k][i][j]代表前k行有i列放了一个炮有j列放了两个炮 那么没放炮的也很容易表示那么状态有如下几种1丶哪一列也不放炮时 f[k][i][j]=f[k-1][i][j]2丶在没有炮的一列放一个炮时 f[k][i][j]=f[k-1][i-1][j]*(m-i-j+1); //由于当前状态是有i列有一个炮 // j列有两个炮 // (m-i-j)列没有炮 //所以推出它上一个状态 有(i-1)列有一个炮 // j列有两个炮 // (m-i-j+1)列没有炮 //没有炮的列都可以放炮 所以是f[k-1][i-1][j]*(m-i-j+1); //其他状态大同小异就不详细解释了3丶在有一个炮的一列放一个炮 f[k][i][j]=f[k-1][i+1][j-1]*(i+1);4丶在没有炮的两列中各放一个炮 f[k][i][j]=f[k-1][i-2][j]*Q(m-j-i+2);//Q的具体含义见代码5丶在有一个炮的两列各放一个炮 f[k][i][j]=f[k-1][i+2][j-2]*Q(i+2);6丶在没有炮和有一个炮的两列中各放一个炮//等同于在没有炮的一列中放两个炮 f[k][i][j]=f[k-1][i][j-1]*(m-i-j+1)*i;
代码:
#include<cstdio>#include<iostream>#define MAXN 101#define MOD 999983#define ll long longusing namespace std;ll f[MAXN][MAXN][MAXN],ans;int n,m;inline void read(int&x) { int f=1;x=0;char c=getchar(); while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();} while(c>='0'&&c<='9') x=10*x+c-48,c=getchar(); x=x*f;}inline int Q(int t) { return t*(t-1)/2;}int main() { freopen("cannon.in","r",stdin); freopen("cannon.out","w",stdout); read(n);read(m); f[0][0][0]=1; for(int k=1;k<=n;k++) for(int i=0;i<=m;i++) for(int j=0;j<=m-i;j++) { f[k][i][j]=f[k-1][i][j]; if(i) f[k][i][j]+=f[k-1][i-1][j]*(m-i-j+1); if(j&&i<m) f[k][i][j]+=f[k-1][i+1][j-1]*(i+1); if(i>1) f[k][i][j]+=f[k-1][i-2][j]*Q(m-i-j+2); if(j>1&&i<m-1) f[k][i][j]+=f[k-1][i+2][j-2]*Q(i+2); if(i&&j) f[k][i][j]+=f[k-1][i][j-1]*(m-i-j+1)*i; f[k][i][j]%=MOD; } for(int i=0;i<=m;i++) for(int j=0;j<=m-i;j++) ans=(ans+f[n][i][j])%MOD; printf("%d\n",ans); fclose(stdin); fclose(stdout); return 0;}
思路:
组合数....真是瞎了我的24K钛合金狗眼竟然看不出来我们让n>m所以n行中最多有m行可以放車也就是在n中选m个数一样的思路...求组合数可以先分解一下质因数 然后把除法去掉 对于只有乘法 只保留最后100位 最后 这要用高精!!!
代码:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define rep(i,x,y) for(i=x;i<=y;i++)#define _rep(i,x,y) for(i=x;i>=y;i--)#define MIN(x,y) ((x)<(y)?(x):(y))const int MAXN=10000010;const int MAXLEN=50;int n,m,i,j;int tot[MAXN];bool pd[MAXN];struct bignumber{ int num; int s[MAXLEN+1]; void clear(){num=0;memset(s,0,sizeof(s));}}ans,now;bignumber operator*(bignumber a,bignumber b){ int i,j; bignumber c;c.clear(); rep(i,1,MIN(MAXLEN,a.num)) rep(j,1,MIN(MAXLEN-i+1,b.num)) c.s[i+j-1]+=a.s[i]*b.s[j]; rep(i,1,MAXLEN) { if(i<MAXLEN)c.s[i+1]+=c.s[i]/10; c.s[i]%=10; } c.num=MAXLEN;while(c.num>1&&c.s[c.num]==0)c.num--; return c;}bignumber pow(int x){ if(x==1)return now; bignumber ans=pow(x/2); ans=ans*ans; if(x&1)ans=ans*now; return ans;}void zhuan(int i){ now.clear(); while(i>0)now.s[++now.num]=i%10,i/=10;}void print(bignumber a){ int i; _rep(i,a.num,1)printf("%d",a.s[i]);printf("\n");}int main(){ freopen("rook.in","r",stdin); freopen("rook.out","w",stdout); scanf("%d%d",&n,&m); if(n<m)swap(n,m); rep(i,1,m)tot[i]-=1; rep(i,n-m+1,n)tot[i]+=1; memset(pd,1,sizeof(pd)); rep(i,2,n) if(pd[i]) _rep(j,n/i,2) { pd[i*j]=0; tot[i]+=tot[i*j]; tot[j]+=tot[i*j]; tot[i*j]=0; } ans.num=1;ans.s[1]=1; rep(i,2,n)if(tot[i]>0)zhuan(i),ans=ans*pow(tot[i]); print(ans); return 0;}
思路:
这个裸暴力只有70分 (尽管我暴力超时不要不要的)(0.0)实际上这题是可以用位运算优化的以行为阶段 记录之前每一列的信息和两条对角线的信息列好办 关键是这个对角线比较丑 因为他是斜着的假设当前行我们放在了i这里 那么下一行的话 就是i左边 和i右边不能放 这里利用位运算的左移右移就好了然后还有些小技巧 就是枚举当前行放在哪利用 lowbit 找最小的不是0的位在哪还有就是 状态记录的时候0表示还可以放但是涉及到 lowbit 这个 我们用的时候去一下反1 表示还可以放 这就非常优美了
代码:
#include<cstdio>using namespace std;#define rep(i,x,y) for(i=x;i<=y;i++)const int MAXN=16;int n,i,j,x,ans;int a[MAXN];void search(int i,int S1,int S2,int S3){ if(i==n){ans++;return;} int j,_S=((1<<n)-1)&(~(a[i]|S1|S2|S3)); while(_S>0) { j=_S&(-_S); search(i+1,S1^j,(S2^j)>>1,(S3^j)<<1); _S-=j; }}int main(){ freopen("queen.in","r",stdin); freopen("queen.out","w",stdout); scanf("%d",&n); rep(i,0,n-1) rep(j,0,n-1) scanf("%d",&x),a[i]+=x<<j; search(0,0,0,0); printf("%d\n",ans); return 0;}
0 0
- 11.2 NOIP模拟赛 (morning)
- 10.30 NOIP模拟赛(morning)
- 10.31 NOIP模拟赛(morning)
- 11.1 NOIP模拟赛(morning)
- 11.3 NOIP模拟赛 (morning)
- 10.29(morning) 模拟赛
- 11.2 NOIP模拟赛 (afternoon)
- 11.1~11.2NOIP模拟赛总结
- noip模拟题 11.2
- noip模拟赛 双城记
- 【noip模拟赛】密码
- 10.10NOIP模拟赛
- 10.08NOIP模拟赛
- 10.11NOIP模拟赛
- 10.12NOIP模拟赛
- 10.13NOIP模拟赛
- 【NOIP模拟赛】小奇挖矿
- NOIP模拟赛--军训
- python 日志模块logging学习与使用(日志分割)
- 自定义view实现阻尼效果的加载动画
- 二进制 八进制 十进制 十六进制
- MyBatis 插入空值时,需要指定JdbcType
- linux flash、分区、文件系统点滴
- 11.2 NOIP模拟赛 (morning)
- JQuery实现checkbox全选和取消全选
- JavaPoet生成.java源代码
- python3 socket抓包
- 第十一周 项目一 -二叉树算法验证(1)层次遍历算法的验证
- 解题报告(5)——流星雨
- 面试题链接
- shiro应用
- STM32F407多通道ADC采样程序