首页 > 代码库 > HDU 1565 状压dp
HDU 1565 状压dp
从第一行到开始,一行一行进行考虑
方格取数(1)
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5751 Accepted Submission(s): 2180
Problem Description
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
Input
包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数(n<=20)
Output
对于每个测试实例,输出可能取得的最大的和
Sample Input
3 75 15 21 75 15 28 34 70 5
Sample Output
188
#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <limits.h> #include <ctype.h> #include <string.h> #include <string> #include <algorithm> #include <iostream> #include <queue> #include <stack> #include <deque> #include <vector> #include <set> #include <map> using namespace std; #define MAXN 18005 int dp[22][MAXN],V[22][22],state[MAXN]; int Max(int a,int b){ return a>b?a:b; } bool canuse(int x){//判断哪些位置是可以的 bool f = false; while(x){ if(x%2 && f){ return false; } if(x%2){ f = true; } else{ f = false; } x>>=1; } return true; } bool legal(int x,int y){//列之间的关系 if(x&y){ return false; } else{ return true; } } int main(){ int i,j,t,x,num,ans,n; while(~scanf("%d",&n)){ num = 0; for(i=0;i<(1<<n);i++){ if(canuse(i)){ state[++num] = i; } } for(i=1;i<=n;i++){ for(j=0;j<n;j++){ scanf("%d",&V[i][j]); } } memset(dp,0,sizeof(dp)); for(t=1;t<=n;t++){ for(i=1;i<=num;i++){ int d = 0; for(x=0;x<n;x++){ if(state[i]&(1<<x)){ d+=V[t][x]; } } for(j=1;j<=num;j++){ if(legal(state[i],state[j])){ dp[t][i] = Max(dp[t][i],d+dp[t-1][j]); } } } } ans = 0; for(i=1;i<=num;i++){ ans = Max(ans,dp[n][i]); } printf("%d\n",ans); } return 0; }
HDU 1565 状压dp
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。