zoj3777(状态压缩)
题目阐述:
给定n个座位,n个人,每个人可以做n个位置中的任意一个,P[i][j]代表第i个人做第j个位置获得的分数,求有多少种排列方式使得获得的分数大于等于M。
这道题跟数位dp的思想很像,都是穷举可能的方式,不过数位DP由于前缀的影响可以记忆化,这道题由于n较小,可以直接状态压缩.
定义状态d[i][s][t]代表已经放了i个座位,放的人数集合为s,获得分数为t的排列的数量。
然后每次暴力枚举每个位置可能会放的人
d[i][s | (1 << j)][t+ p[j][i]] +=d[i-1] [s] [t];
重点是如何实现:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define maxn 13
using namespace std;
int d[<<(maxn)][]; //表示到达状态s时产生的最大能量
int n,m;
int P[maxn][maxn];
int ans;
void init()
{
ans=;
memset(d,,sizeof(d));
}
//GCD
//求最大公约数
//O(logn)
int gcd(int a, int b)
{
if (b == )
return a;
else
return gcd(b, a%b);
}
int isok(int i)
{
int t=;
while(i)
{
if(i&) t++;
i>>=;
}
return t;
}
void solve()
{
int tot=(<<n)-;
d[][]=; //其实可以理解成d[-1][0][0],否则下面就需要特殊处理i等于0
for(int i=;i<n;i++) //代表第i个位置
{
for(int s=;s<=tot;s++) //遍历所有状态
{
if(isok(s)!=i) continue ;//检测哪些是前i-1个位置的状态
for(int t=;t<=m;t++) //遍历所有获得的分数
{
if(!d[s][t]) continue; //检测哪些是前i-1个位置获得的分数
for(int j=;j<n;j++) //枚举第i个位置可能放的人
{
if( s & (<<j) ) //检测前i-1个位置是否放过
continue;
int state= s | (<<j);
int MM=min(m,t+P[j][i]);
d[state][MM]+=d[s][t];
}
}
}
}
ans=d[tot][m];
} int main()
{
// freopen("test.txt","r",stdin);
int fac[maxn];
fac[]=;
for(int i=;i<maxn;i++)
fac[i]=fac[i-]*i;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
for(int i=;i<n;i++)
for(int j=;j<n;j++)
{
scanf("%d",&P[i][j]);
}
solve();
int d = gcd(fac[n], ans);
if (ans == )
printf("No solution\n");
else
printf("%d/%d\n", fac[n]/d, ans/d);
}
return ;
}
bfs实现:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#define maxn 13
using namespace std;
int d[<<(maxn)][]; //表示到达状态s时产生的最大能量
int n,m;
int P[maxn][maxn];
int ans;
int gcd(int a, int b)
{
if (b == )
return a;
else
return gcd(b, a%b);
} int bit(int i)
{
int t=;
while(i)
{
if(i&) t++;
i>>=;
}
return t;
}
struct node
{
int s,t,cnt=;
};
int visit[<<maxn][];
void bfs()
{
queue < node > que;
memset(visit,,sizeof(visit));
int tot=(<<n)-;
node start,last;
start.s=; start.t=;
start.cnt=;
que.push(start);
visit[start.s][start.t]=;
d[][]=;
while(!que.empty())
{
node cur=que.front();
que.pop();
for(int i=;i<n;i++)
{
if(cur.s & (<<i))
continue;
node next ;
next.s= cur.s | (<<i);
next.cnt=cur.cnt+;
next.t= min(m,cur.t+P[i][cur.cnt]); //将第i个人放在当前位置,然后才会加1
d[next.s][next.t] += d[cur.s][cur.t];
if(visit[next.s][next.t]) //保证只进队一次
continue;
que.push(next);
visit[next.s][next.t]=;
}
}
ans=d[tot][m];
} int main()
{
// freopen("test.txt","r",stdin);
int fac[maxn];
fac[]=;
for(int i=;i<maxn;i++)
fac[i]=fac[i-]*i;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
ans=;
memset(d,,sizeof(d));;
for(int i=;i<n;i++)
for(int j=;j<n;j++)
{
scanf("%d",&P[i][j]);
}
bfs();
int d = gcd(fac[n], ans);
if (ans == )
printf("No solution\n");
else
printf("%d/%d\n", fac[n]/d, ans/d);
}
return ;
}
zoj3777(状态压缩)的更多相关文章
- POJ 3254. Corn Fields 状态压缩DP (入门级)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9806 Accepted: 5185 Descr ...
- HDU 3605:Escape(最大流+状态压缩)
http://acm.hdu.edu.cn/showproblem.php?pid=3605 题意:有n个人要去到m个星球上,这n个人每个人对m个星球有一个选择,即愿不愿意去,"Y" ...
- [HDU 4336] Card Collector (状态压缩概率dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4336 题目大意:有n种卡片,需要吃零食收集,打开零食,出现第i种卡片的概率是p[i],也有可能不出现卡 ...
- HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)
题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由 ...
- codeforces B - Preparing Olympiad(dfs或者状态压缩枚举)
B. Preparing Olympiad You have n problems. You have estimated the difficulty of the i-th one as inte ...
- NOIP2005过河[DP 状态压缩]
题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数 ...
- vijos1426兴奋剂检查(多维费用的背包问题+状态压缩+hash)
背景 北京奥运会开幕了,这是中国人的骄傲和自豪,中国健儿在运动场上已经创造了一个又一个辉煌,super pig也不例外……………… 描述 虽然兴奋剂是奥运会及其他重要比赛的禁药,是禁止服用的.但是运动 ...
- hoj2662 状态压缩dp
Pieces Assignment My Tags (Edit) Source : zhouguyue Time limit : 1 sec Memory limit : 64 M S ...
- poj3254 状态压缩dp
题意:给出一个n行m列的草地,1表示肥沃,0表示贫瘠,现在要把一些牛放在肥沃的草地上,但是要求所有牛不能相邻,问你有多少种放法. 分析:假如我们知道第 i-1 行的所有的可以放的情况,那么对于 ...
随机推荐
- 【UTR #2】[UOJ#278]题目排列顺序 [UOJ#279]题目交流通道 [UOJ#280]题目难度提升
[UOJ#278][UTR #2]题目排列顺序 试题描述 “又要出题了.” 宇宙出题中心主任 —— 吉米多出题斯基,坐在办公桌前策划即将到来的 UOI. 这场比赛有 n 道题,吉米多出题斯基需要决定这 ...
- poj 3683 2-sat问题,输出任意一组可行解
/* 2sat问题 输出任意一组可行解 */ #include<stdio.h> #include<string.h> #include<stdlib.h> #in ...
- bzoj4027 [HEOI2015]兔子与樱花 树上贪心
[HEOI2015]兔子与樱花 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1320 Solved: 762[Submit][Status][Di ...
- msp430项目编程32
msp430中项目---电阻测量系统32 Ad 1.电路工作原理 2.代码(显示部分) 3.代码(功能实现) 4.项目总结
- linux 安装报错:pkg-config not found
linux 安装报错:pkg-config not found 使用编译安装时,在执行./configure时报如下错误: ... ... checking for pkg-config... no ...
- APP后端处理表情的一些技巧
app应用中文字夹带表情是个很常见的现象.甚至一些40多岁的大叔级用户,也喜欢在自己的昵称中夹带表情,在产品运营后发现这个现象,彻底颠覆了我的世界观. 在后台处理表情的时间,我遇到过下面3个问题: 1 ...
- CodeForces 593A 2Char
暴力. #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> u ...
- 洛谷——P2434 [SDOI2005]区间
P2434 [SDOI2005]区间 题目描述 现给定n个闭区间[ai, bi],1<=i<=n.这些区间的并可以表示为一些不相交的闭区间的并.你的任务就是在这些表示方式中找出包含最少区间 ...
- hdu 4971
记忆花搜索 dp #include <cstdio> #include <cstdlib> #include <cmath> #include <set& ...
- ArcEngine读取ShapeFile时,出现乱码的解决方案
ArcEngine读取ShapeFile时,如果用LicenseControl的话,字段中含有汉字时可以正常使用,当使用LicenseInitializer进行初始化时,读取含有汉字的字段时,就会出现 ...