hdu2167Pebbles
来源:互联网 发布:淘宝网服饰香柳儿 编辑:程序博客网 时间:2024/05/17 07:36
状态压缩的模板题。。。
题意:给你一个N*N( 3<=N<=15)个矩阵,要你选择若干个数(每个数的范围在[10,99]),使得最后所选的数总和最大。选数的规则是如果选了某个数,那么它的八个相邻方向的数都不能选。
刚开始学还是有难度的,这还是我状压第一题。
方法:先状态压缩,将矩阵看作二进制变成一个数,再以第1行为例枚举出所有的情况与最优解,存在v,f数组,再更新下面2~n行,枚举过程中判断异或一下上、上左、上右有没有选过即可
代码:
#include<cstdio>#include<iostream>#include<cstring>#include<sstream>using namespace std;int f[20][(1<<15)+10];int n,a[20][20],vn,v[(1<<15)+10],bit[20];char s[110000];int main(){ bit[1]=1;for(int i=2;i<=15;i++)bit[i]=bit[i-1]*2; while(gets(s)) { stringstream ss(s); n=0;while(ss>>a[1][++n]);n--; for(int i=2;i<=n;i++) for(int j=1;j<=n;j++)scanf("%d",&a[i][j]); gets(s);gets(s); memset(f,0,sizeof(f)); int mmax=(1<<n)-1;vn=0; for(int x=0;x<=mmax;x++) if(((x<<1)&x)==0) { for(int j=1;j<=n;j++) if((bit[j]&x)==bit[j])f[1][x]+=a[1][j]; v[++vn]=x; } for(int i=2;i<=n;i++) for(int p=1;p<=vn;p++) { int tt=0;for(int j=1;j<=n;j++) if((bit[j]&v[p])!=0)tt+=a[i][j]; for(int q=1;q<=vn;q++) if((v[q]&v[p])==0&&((v[q]<<1)&v[p])==0&&((v[q]>>1)&v[p])==0) f[i][v[p]]=max(f[i][v[p]],f[i-1][v[q]]+tt); } int ans=0;for(int p=1;p<=vn;p++) if(ans<f[n][v[p]])ans=f[n][v[p]]; printf("%d\n",ans); } return 0;}
By_yzh
4 1
- hdu2167Pebbles
- hdu2167Pebbles dp+状态压缩水题
- JAVA序列化标准格式(XML、JSON)
- TCP的三次握手原理和四次挥手
- android 实现带动画可拖拽gridview
- [Python]网络爬虫(四):Opener与Handler的介绍和实例应用
- [hdu2167]Pebbles
- hdu2167Pebbles
- 微信发红包UITextField金额输入格式化
- 牛人主页(主页有很多论文代码)
- Android中shape属性详解
- JAVA并发编程学习笔记之AQS源码分析(获取与释放)(r)
- PLSQL导出大量数据-超出excel限制,使用csv
- python打包工具比较
- TOP to Down设计简单例子 Creo3.0
- 腾讯高级工程师:一道面试题引发的高并发性能调试思考