hdu1565 用搜索代替枚举找可能状态或者轮廓线解(较优),参考poj2411
2024-08-26 08:30:25
这题用直接枚举是超时的,必须要用搜索来搜索出所有可能的状态,然后再进行枚举
这是较慢的做法
/*
方格取数,相邻格子的数不可取,问最多取到的和是什么
有点类似炮兵布阵,先打出所有可能的状态,然后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);
}
}
最新文章
- 在Linux中打印函数调用堆栈【原创】
- sql访注入
- [转]iOS应用性能调优的25个建议和技巧
- C++学习——类的继承
- 【LeetCode 209】Minimum Size Subarray Sum
- JavaScript元素的创建、添加、删除
- id名和class名有什么区别
- Android 给TextView添加点击事件
- LP64是什么意思
- 【贪心】【HDU3177】 搬家问题
- maven 编
- java 缓冲流
- JNI中的内存管理(转)
- MATLAB实现聚类
- 从一个国内普通开发者的视角谈谈Sitecore
- Vcenter 账户密码过期设置修改
- textarea的高度随内容变化而变化
- 配置Tree Shaking来减少JavaScript的打包体积
- FastReport动态绑定只显示一条数据。
- jenkins基于gradle打包说明