HDU1565—方格取数(1)——状压DP
来源:互联网 发布:啥软件机票便宜 编辑:程序博客网 时间:2024/06/05 09:06
Problem Description
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
Input
包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数(n<=20)
Output
对于每个测试实例,输出可能取得的最大的和
Sample Input
3
75 15 21
75 15 28
34 70 5
Sample Output
188
本题思路::肯定是状态压缩的DP。把每一种可能的状态存放在 mp 数组中,共有tot种状态。用 dp 二维数组记录最大值。其中dp[ i ][ j ]表示到第 i 行 j 状态的最大值。状态转变方程为dp[ i ][ j ] = max(dp[ i ][ j ] , dp[ i-1 ][ k ] + sum[ j ]); 其中dp[ i - 1 ][ k ]表示第 i - 1 行 k 状态 ,sum 为 i 行 j 状态的总和。详情看代码。
//这道题的关键在于时间和空间复杂度思路还是比较简单//第一次::把每一个状态都记录在数组中,超了空间//第二次::把不可能的状态踢掉,超了时间//第三次::看了网上的题解,发现可以把当前行,和上一行换位置,节省了大量时间,过掉了#include <iostream>#include <sstream>#include <ios>#include <iomanip>#include <functional>#include <algorithm>#include <vector>#include <string>#include <list>#include <queue>#include <deque>#include <stack>#include <set>#include <map>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <climits>#include <cctype>using namespace std;#define XINF INT_MAX#define INF 0x3FFFFFFF#define MP(X,Y) make_pair(X,Y)#define PB(X) push_back(X)#define REP(X,N) for(int X=0;X<N;X++)#define REP2(X,L,R) for(int X=L;X<=R;X++)#define DEP(X,R,L) for(int X=R;X>=L;X--)#define CLR(A,X) memset(A,X,sizeof(A))#define IT iteratortypedef long long ll;typedef pair<int,int> PII;typedef vector<PII> VII;typedef vector<int> VI;//const int MAXN = 10010;//#define INF 0x3FFFFFFF/********************************************************头文件*********************************************************/int mp[20000]; //曾经尝试用map,后来发现和数组功能完全相同int dp[20][20000];//可以进一步改为滚动数组可节省空间int maps[23][23];//记录值int main(){int n;while(cin>>n){memset(dp,0,sizeof(dp));REP2(i,1,n)//这里从第一行开始记录REP(j,n)//这里从第零列开始记录{ cin>>maps[i][j];}int tot = 0;//tot用来记录有多少种可能性for(int i =0;i<(1<<n);i++)//遍历每一种情况{if(i & (i << 1)) continue; //出现相邻直接过掉mp[tot++] =i;}int ans = 0;//用来记录结果for(int i = 0; i < n; i++){//遍历每一行因为从0开始,所以下面为i+1for(int j = 0; j < tot; j++){ //遍历当前行的每一种状态 int sum = 0;//用来记录当前状态第i+1行的总和 REP(l,n){ int t = 1<<l; if(mp[j]&t) sum += maps[i+1][l];}for(int k = 0; k < tot; k++){ //遍历上一行状态if(mp[j] & mp[k]) continue; //两行之间有相邻dp[i+1][j] = max(dp[i+1][j],sum+dp[i][k]);//截止到i+1行为j状态是的最大值ans = max(ans,dp[i+1][j]);//答案应取每一个最大状态的最大值}}}cout<<ans<<endl;}return 0;}
0 0
- HDU1565—方格取数(1)——状压DP
- HDU1565 方格取数(1) —— 状压DP
- HDU1565——方格取数(1)
- hdu1565 方格取数(1)(状压dp)
- hdu1565 方格取数(1)
- 【HDU1565】方格取数1
- HDU1565 方格取数(1) (状态压缩DP)
- HDU1565:方格取数(1) (状态压缩DP)
- HDU1565方格取数(1)(状态压缩DP)
- HDU1565方格取数
- HDU1565 方格取数(1)网络流
- HDU1565 方格取数(1) 网络流
- hdu1565方格取数(1)【状态压缩】
- HDU1565 方格取数(1) 题解
- hdu1565方格取数(1) (最大权独立集)
- hdu1565 方格取数(1)&&hdu1569 方格取数(2)(最小割)
- hdu1565 hdu1569 方格取数 最小割
- hdu1565 方格取数(状态压缩)
- hdu1551Cable master(二分*)
- hdoj 2199 Can you solve this equation?【二分法】
- Android进程内通信
- hdu5328_Problem Killer(简单dp)
- UVA 12594 Naming Babies (斜率优化DP)
- HDU1565—方格取数(1)——状压DP
- c++ 流基本概念
- [BZOJ2326][HNOI2011]数学作业
- poj1061青蛙那啥,第一次弄欧几里德,各种问题各种请教
- Elasticsearch、MongoDB和Hadoop比较
- BAPI_NETWORK_COMP_ADD
- nyoj 23 取石子(一)【博弈论】
- [BZOJ1015][JSOI2008]星球大战starwar
- 浏览器引擎