这题用直接枚举是超时的,必须要用搜索来搜索出所有可能的状态,然后再进行枚举

这是较慢的做法

/*
方格取数,相邻格子的数不可取,问最多取到的和是什么
有点类似炮兵布阵,先打出所有可能的状态,然后dp[i][j]表示前i行在状态v[j]下的最大和
dp[i][j]由dp[i-1][t]推出,v[t]是和v[j]兼容的状态
*/
#include<bits/stdc++.h>
using namespace std;
int mp[][],n,dp[][];
int v[],tot;
vector<int>sum[];//sum[i][j]表示第i行在状态v[j]下的和
inline int legal(int j){
if( j&(j<<) )return false;
return true;
}
inline int cal(int s,int k){//状态s对应的数值
int res=;
for(int i=;i<=n;i++)
if( s&(<<(i-)) )res+=mp[k][n-i+];
return res;
}
void init(){
tot=;
for(int j=;j<=(<<n)-;j++)
if(legal(j))v[tot++]=j;
} int main(){
while(cin>>n){
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)cin>>mp[i][j];
init();
memset(dp,,sizeof dp);
for(int i=;i<tot;i++)
dp[][i]=cal(v[i],); for(int i=;i<=n;i++)
for(int j=;j<tot;j++){//枚举i行的状态
for(int k=;k<tot;k++){//枚举k行的状态
if( v[k]&v[j] )continue;
dp[i][j]=max(dp[i][j],dp[i-][k]+cal(v[j],i));
}
} int ans=;
for(int i=;i<tot;i++)
ans=max(ans,dp[n][i]);
printf("%d\n",ans);
}
}

最新文章

  1. 在Linux中打印函数调用堆栈【原创】
  2. sql访注入
  3. [转]iOS应用性能调优的25个建议和技巧
  4. C++学习——类的继承
  5. 【LeetCode 209】Minimum Size Subarray Sum
  6. JavaScript元素的创建、添加、删除
  7. id名和class名有什么区别
  8. Android 给TextView添加点击事件
  9. LP64是什么意思
  10. 【贪心】【HDU3177】 搬家问题
  11. maven 编
  12. java 缓冲流
  13. JNI中的内存管理(转)
  14. MATLAB实现聚类
  15. 从一个国内普通开发者的视角谈谈Sitecore
  16. Vcenter 账户密码过期设置修改
  17. textarea的高度随内容变化而变化
  18. 配置Tree Shaking来减少JavaScript的打包体积
  19. FastReport动态绑定只显示一条数据。
  20. jenkins基于gradle打包说明

热门文章

  1. Centos 02 操作系统 &amp; Linux安装
  2. python第一天,简单输出及基本运算符
  3. apache fileupload 文件上传,及文件进度设置获取
  4. JAVA并行异步编程,线程池+FutureTask
  5. 20165325《Java程序设计》第九周学习总结
  6. 为什么要重写equals和hashcode方法
  7. Python-字符串的常用操作
  8. Scala 继承
  9. FAT文件系统规范v1.03学习笔记---4.文件和目录数据区之长目录项
  10. delete指针以后应赋值为NULL