hdu_1565_方格取数(1)
来源:互联网 发布:网络人肉违法 编辑:程序博客网 时间:2024/04/30 21:18
各种裸的状态压缩嗯~
中文题就就不翻译了~
http://acm.hdu.edu.cn/showproblem.php?pid=1565
解题思想:
有两个比较重要的地方:
1. 纪录可行状态. 例如当前状态i为101011,那么判定状态是否可行为(i&(i<<1))也就是相邻位去&,若为1则不可行.对于一个20个的数组一共有28658种可行状态,判定后直接打表.
2. dp[2][M]作为滚动数组,我的方法是两个指针交换(很多人都用奇偶数的方法).先初始化第一行,dp[0][i]为第i种状态的总值为多少.接下来对每一行的每一种状态,求其上一行的与其不冲突状态的最大值.
源代码:
#include <myhead.h>const int N=21;const int M=(1<<21);const int NUM=28658;int n,num;int state[NUM];int data[N][N];int dp[2][NUM];void build() {num=0;for(int i=0;i<M;++i) {if(i&(i<<1)) continue;state[num++]=i;}//printf("%d\n",num);}void init() {num=(1<<n);memset(dp,-1,sizeof(dp));for(int i=0;i<n;++i) {for(int j=0;j<n;++j) {scanf("%d",&data[i][j]);}}}int getDp(int x,int m) {int sum=0;int t=0;while(m) {if(m&1) {sum+=data[x][t];}m>>=1;t++;}return sum;}void work() {int *a=dp[0];int *b=dp[1];for(int i=0;state[i]<num;++i) {a[i]=getDp(0,state[i]);}for(int k=1;k<n;++k) {for(int i=0;state[i]<num;++i) {int max=-1;for(int j=0;state[j]<num;++j) {if(a[j]!=-1 && !(state[j]&state[i])) {checkmax(max,a[j]);}}b[i]=max+getDp(k,state[i]);}swap(a,b);}int ans=-1;for(int i=0;state[i]<num;++i) {checkmax(ans,a[i]);}printf("%d\n",ans);}int main() {build();while(~scanf("%d",&n)) {init();work();}return 0;}
- hdu_1565_方格取数(1)
- HDU_1565_方格取数(1)
- 方格取数(1)
- 方格取数(1)
- U - 方格取数(1)
- hdu1565 方格取数(1)
- 【HDU1565】方格取数1
- 方格取数(1) HDU
- HDU 1565 方格取数(1)
- hdu 1565 方格取数(1)
- HDU-1565-方格取数(1)
- hdu 1565 方格取数(1)
- HDU 1565 方格取数(1)
- HDU1565 方格取数(1)网络流
- hdu(1565)方格取数(1)
- hdu 1565 方格取数(1)
- hdu 1565 方格取数(1)
- hdu 1565 方格取数(1)
- Android之Android的数据存储--File
- 解决打ejb-client包jdk版本问题
- S3C2440裸奔之一 关于启动代码
- dynamic_cast<>
- 分布式RMI多IP紊乱问题
- hdu_1565_方格取数(1)
- 32寄存器大全
- KMP算法详解
- KMP算法实现
- red5+ffmpeg
- Redis源码分析之事务
- OCM 考试说明
- poj 3070 Fibonacci
- zoj1665-Transport Goods