Regionals 2009 Asia - Hsinchu UVALIVE, 4525 - Clues 搜索
来源:互联网 发布:单片机的32个引脚介绍 编辑:程序博客网 时间:2024/06/04 22:26
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=350&page=show_problem&problem=2526
题目大意:
话说岛国有位博士,想要保护一个数据的安全,这个数是个质数,假设是k0。他的策略是这样的,首先他选择一个r,r>=1,和一个空集合C,然后选择r-1个不超过k0的质数,k1,k2,。。。,k(r-1),然后把r加到集合C中。第二步,对于每一个k0到k(r-1)。他要么直接把k放进集合,要么把k拆成几个数(随便拆,只要和等于k就行)然后把拆出来的数放进集合。最后一步,将集合里面所有的数按照非递减的顺序排列。
由于教授年纪有些大了,脑子不太好使,让你帮他个忙,通过最后的集合找出原来的k,对于饱经ACM训练的你来说,这还不是小菜一碟,一听老教授的要求,灵光一动,便老练的说到,“你这个有多种情况啊”,只见年迈的老教授眼中精光一闪,心想,“小伙子有几把刷子啊”,“这样吧,那你就找出你能恢复出来的最大质数好了”。
于是,善良的你,便不知不觉落进了猎人的圈套。。
思路:
首先,根据题目要求,集合中肯定有一个r,也就是最终质数的个数。那么首先枚举r,然后对于剩下的元素,由于元素个数最多只有14个,那么可以用二进制枚举的形式,找出能够组成的所有质数,判断这些质数对应二进制集合相互没有交集能否组成r个,并找出能组成的最大值就是最后答案。
对于每一个r,和所有剩下元素组成的质数集合,可以用dp来进行后续的判断。
dp[i][s]表示s所有二进制位为1那一位对应的数的集合组成i个质数后其中最大的质数。
那么,对于质数集合中的一个质数v,以及对应的二进制集合t,如果t与s没有交集,即s&t==0,那么,
dp[i+1][s|t] = max(dp[i+1][s|t],max(dp[i][s],v));
最后dp[r][(1<<n-1)-1] 就是当前r对应的质数最大值。
代码:
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;#define maxn 200000#define inf 0x3fffffffint n;int a[20],b[20];bool fac[maxn];int ans;struct Node{int val;int s;Node(){}Node(int a,int b):val(a),s(b){}};vector<Node> vec;int dp[20][maxn];void init(){memset(fac,false,sizeof(fac));fac[0] = fac[1] = true;for(int i=2;i<maxn;i++){if(!fac[i]){for(int j=i*2;j<maxn;j+=i){fac[j] = true;}}}//for(int i=2;i<100;i++){//if(!fac[i]) printf("%d\n",i);//}}void check(int r){for(int i=0;i<=r;i++){for(int s=0;s<1<<(n-1);s++) dp[i][s] = 0;}for(int i=0;i<vec.size();i++) dp[1][vec[i].s] = vec[i].val;for(int i=1;i<r;i++){for(int s=0;s<1<<(n-1);s++){if(dp[i][s]==0) continue; //当前状态无法拼出质数 for(int k=0;k<vec.size();k++){if(s&vec[k].s) continue; //vec[i].s 存在元素已经被选择int t = vec[k].s;dp[i+1][s|t] = max(dp[i+1][s|t],max(vec[k].val,dp[i][s]));}}}ans = max(ans,dp[r][(1<<(n-1))-1]);}void solve(){ans = 0;for(int i=0;i<n && a[i]<n;i++){ // 枚举r if(i>0 && a[i]==a[i-1]) continue; // 避免重复 memcpy(b,a,sizeof(a));b[i] = inf; // b[i] is rswap(b[i],b[n-1]);vec.clear(); for(int s=0;s<1<<(n-1);s++){int sum = 0;for(int k=0;k<n-1;k++){if(s&(1<<k)) sum += b[k]; //枚举所有能够拼出的质数 存放到vec中 }if(!fac[sum]) {vec.push_back(Node(sum,s));//printf("r:%d sum:%d\n",a[i],sum);}}check(a[i]);//printf("xxxxxxxxxxxxxxx\n");}if(ans==0) printf("not a valid clue\n");else printf("%d\n",ans);}int main(){init();int cnt=1;while(scanf("%d",&n)){if(n==-1) break;for(int i=0;i<n;i++) scanf("%d",&a[i]);printf("Case %d: ",cnt++);solve();}return 0;}
- Regionals 2009 Asia - Hsinchu UVALIVE, 4525 - Clues 搜索
- Regionals 2009 :: Asia - Hsinchu UVALIVE, 4527 Vaccination Centers - 搜索剪枝
- Regionals 2009 >> Asia - Hsinchu UVALIVE, 4528 Schedule Pairs of Jobs - 搜索回溯
- Regionals 2009 >> Asia - Hsinchu UVALIVE, 4529 A Constrained Queen Game - 搜索剪枝
- Regionals 2009 Asia - Hsinchu uvalive 4526 Inventory - dp
- UVALive 4264 Message(Regionals 2008 :: Asia - Taipei+模拟)
- UVALive Problem 7454 Parentheses——Regionals 2015 :: Asia - Taipei
- UVALive 6265 Graphic Madness 搜索 Regionals 2012 :: Europe - Central
- UVALive 4260 Fortune Card Game (Regionals 2008 Asia Taipei +DP)
- Uvalive 4267 Finding The Heaviest Path (Regionals 2008 Asia Taipei +DFS结点最大权值路径)
- UVALive Problem 7457 Discrete Logarithm Problem——Regionals 2015 :: Asia - Taipei
- UVALive Problem 7456 Least Crucial Node——Regionals 2015 :: Asia - Taipei
- Regionals 2011, Asia - Amritapuri
- Regionals 2011, Asia - Phuket
- Regionals 2010, Asia - Amritapuri
- Regionals 2011, Asia - Daejeon
- Regionals 2011, Asia - Kanpur
- Regionals 2012 :: Asia - Amritapuri
- PID算法实战之利用PWM控制LED以使光敏电阻稳定在特定值
- UI016----图片缩放
- 尉本坏局澳刹磕雇
- [Java Concurrency in Practice]第三章 对象的共享
- 凸虏宰麓匦盎圆斜
- Regionals 2009 Asia - Hsinchu UVALIVE, 4525 - Clues 搜索
- c++ stl
- 哪降欧牢叹匾叹吩
- VC++的Unicode编程
- bash多进程与wait,sleep区别
- 傥膛诺澄凡嘶诎嘎
- 引用字体
- [2015-08-08] python019
- CF_560A_CurrencySystemInGeraldion