hunnu 11463 信封问题 (找规律||搜索)
来源:互联网 发布:网络小说家怎么赚钱 编辑:程序博客网 时间:2024/05/28 17:04
题目链接:点击打开链接
题目大意:全错排问题,指定了某些信封装的信的对于编号,求全错排的解~~~~
刚开始拿到这个题目感觉无从下手,无法保存搜索过程的状态,遂找到对应答案相同的解的特点,打表找到了某个稀里糊涂的规律,2333
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;typedef long long llt;const int MAXN=1100;const int MOD=1000000007;int env[MAXN];llt dp[MAXN][MAXN];void init(){dp[0][0]=1;dp[1][0]=0;dp[1][1]=0;dp[2][1]=1;for(int i=2;i<=1000;i++)dp[i][0]=(dp[i-1][0]+dp[i-2][0])*(i-1)%MOD;for(int i=4;i<=1000;i+=2) dp[i][i/2]=dp[i-2][(i-2)/2]*(i/2)%MOD;for(int j=1;j<=500;j++)for(int i=2*j+1;i<=1000;i++)dp[i][j]=((i-j)*dp[i-1][j]%MOD+MOD-j*dp[i-3][j-1]%MOD)%MOD;}int main() { int n; init(); while(scanf("%d",&n)!=EOF) { int ret=0,hook=0; bool flag=false; for(int i=1;i<=n;i++) { scanf("%d",&env[i]); if(env[i]) ret++; if(env[i]==i) flag=true; } if(flag) { puts("0"); continue; } for(int i=1;i<=n;i++) if(env[env[i]]) hook++; printf("%d\n",dp[n-hook][ret-hook]); } return 0;}后面还发现另一种容易理解的解法~~~
#include <cstdio>#include <cstring>using namespace std;int a[1010];bool f[1010];__int64 dp[1010][1010];const __int64 mod=1000000007LL;__int64 dfs(int,int);void debug(){ for(int i=0;i<=9;i++) { for(int j=0;j<=i/2;j++) printf("DP[%d][%d] :%-4d ",i,j,dfs(i,j)); putchar('\n'); }}//a个不能放在其原本位置,b个可以放在任意位置__int64 dfs(int a,int b){ if(a<0||b<0) return 0; if(dp[a][b]>=0) return dp[a][b]; __int64 ret; //如果b的数量为0,就变成了全错排问题 if(b==0) ret=(a-1)*(dfs(a-1,0)+dfs(a-2,0)); //else ret=dfs(a+1,b-1)+dfs(a,b-1);//玄学问题,这个也能过,不过过程不理解 else ret=a*dfs(a-1,b)+b*dfs(a,b-1); ret%=mod; return dp[a][b]=ret;}int main(){ int i,n,cnta,cntb; //freopen("1.in","r",stdin); //freopen("1.out","w",stdout); bool flag; memset(dp,-1,sizeof(dp)); dp[0][0]=1; debug(); while(scanf("%d",&n)!=EOF) { memset(f,0,sizeof(f)); for(i=1;i<=n;i++) scanf("%d",&a[i]); cnta=cntb=0; flag=1; for(i=1;i<=n;i++) if(a[i]!=0) { if(f[a[i]]==1||a[i]==i) flag=0; f[a[i]]=1; } for(i=1;i<=n;i++) if(a[i]==0) { if(f[i]==0) cnta++; else cntb++; } ///cnta表示不能放在其原本位置的信封的个数 ///cntb表示可以随意放置的信封数量 if(!flag) printf("0\n"); else printf("%I64d\n",dfs(cnta,cntb)); } return 0;}
(最近写题解越来越不走心了,233333333,如果有HUNNU的小伙伴在有生之年能看到我这篇题解,看不懂就直接来问我吧,233333333~~~~~)
阅读全文
0 0
- hunnu 11463 信封问题 (找规律||搜索)
- HDU4671 找规律排列问题
- 简单找规律问题列表
- hdu1021-斐波拉契问题 找规律
- HUNNU Contest 找数字2
- POJ 1218 囚犯问题 数学题找规律
- FOJ 1062 洗牌问题 // 找规律,模拟
- 【找规律】HDU1210Eddy's 洗牌问题
- hdoj2065 "红色病毒"问题 (找规律)
- FZU1062 洗牌问题(找规律)
- 【商旅问题、找规律】ZOJ 1037 Gridland
- 博弈问题方法单-----找规律篇
- 找规律
- 找规律!
- 找规律
- 找规律,
- 找规律
- 找规律
- Android 防止连续点击两次控制
- MySQL高可用架构之MHA
- 阶段性 技术总结
- SQL 别名
- centos7 apache部署项目
- hunnu 11463 信封问题 (找规律||搜索)
- Eclipse 接口开发(一)
- MindManager可以为您和您的团队做些什么?
- 20171215.03
- JavaScript的函数支持重载吗?
- String类实现
- 分布式开发--数据库中间件
- 解决Eclipse中跟代码无法查看源码变量信息
- 递归算法2