HDU 1565——方格取数(1)
2013-05-08 23:29
351 查看
状态压缩DP
每行最多有20个格子,每个格子取用1表示,不取用0表示。
3
75 15 21
75 15 28
34 70 5
188
这样每一行的状态都能用一个数字来,例如75 15 21,如果取75和21,则用101也就是5.
#include<iostream>
#include<cstring>
using namespace std;
int map[24][24];
int num[24];
int str[17720],N;
int dp[2][17720];
bool judge(int x)
{
int end=0;
while(x)
{
if(end==1&&x%2)
return 0;
end=x%2;
x/=2;
}
return 1;
}
void init()
{
int i;
num[1]=1;
for(i=2;i<=20;i++)
num[i]=num[i-1]<<1;
N=1;
for(i=1;i<=num[20];i++)
if(judge(i))
str[N++]=i;
// cout<<N; //N=17711 在这里可以计算出取得格子不相连的状态数
}
int Max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int n;
int max;
int i,j;
init();
while(cin>>n)
{
int i,j,k;
max=0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
cin>>map[i][j];
memset(dp,0,sizeof(dp));
for(i=1;i<=N;i++)//考虑第一层的状态
{
if(str[i]>num[n+1])//状态
break;
for(j=1;j<=n;j++)//计算当前状态能获得的权值
{
if(str[i]&num[j])
dp[0][i]+=map[1][j];
}
}
for(k=2;k<=n;k++)
{
for(i=1;i<=N;i++)
{
int temp=0;
if(str[i]>num[n+1])
break;
for(j=1;j<=n;j++)
{
if(str[i]&num[j])
temp+=map[k][j];
}
for(j=1;j<=N;j++)
{
if(!(str[i]&str[j]))
dp[1][i]=Max(dp[1][i],dp[0][j]+temp);
}
}
for(i=1;i<=N;i++)
{
if(str[i]>num[n+1])
break;
dp[0][i]=dp[1][i];
dp[1][i]=0;
}
}
max=0;
for(i=1;i<=N;i++)
{
if(str[i]>num[n+1])
break;
max=Max(dp[0][i],max);
}
cout<<max<<endl;
}
return 0;
}
每行最多有20个格子,每个格子取用1表示,不取用0表示。
3
75 15 21
75 15 28
34 70 5
188
这样每一行的状态都能用一个数字来,例如75 15 21,如果取75和21,则用101也就是5.
#include<iostream>
#include<cstring>
using namespace std;
int map[24][24];
int num[24];
int str[17720],N;
int dp[2][17720];
bool judge(int x)
{
int end=0;
while(x)
{
if(end==1&&x%2)
return 0;
end=x%2;
x/=2;
}
return 1;
}
void init()
{
int i;
num[1]=1;
for(i=2;i<=20;i++)
num[i]=num[i-1]<<1;
N=1;
for(i=1;i<=num[20];i++)
if(judge(i))
str[N++]=i;
// cout<<N; //N=17711 在这里可以计算出取得格子不相连的状态数
}
int Max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int n;
int max;
int i,j;
init();
while(cin>>n)
{
int i,j,k;
max=0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
cin>>map[i][j];
memset(dp,0,sizeof(dp));
for(i=1;i<=N;i++)//考虑第一层的状态
{
if(str[i]>num[n+1])//状态
break;
for(j=1;j<=n;j++)//计算当前状态能获得的权值
{
if(str[i]&num[j])
dp[0][i]+=map[1][j];
}
}
for(k=2;k<=n;k++)
{
for(i=1;i<=N;i++)
{
int temp=0;
if(str[i]>num[n+1])
break;
for(j=1;j<=n;j++)
{
if(str[i]&num[j])
temp+=map[k][j];
}
for(j=1;j<=N;j++)
{
if(!(str[i]&str[j]))
dp[1][i]=Max(dp[1][i],dp[0][j]+temp);
}
}
for(i=1;i<=N;i++)
{
if(str[i]>num[n+1])
break;
dp[0][i]=dp[1][i];
dp[1][i]=0;
}
}
max=0;
for(i=1;i<=N;i++)
{
if(str[i]>num[n+1])
break;
max=Max(dp[0][i],max);
}
cout<<max<<endl;
}
return 0;
}
相关文章推荐
- hdu 1565 方格取数(1) (状态压缩DP)
- hdu 1565 方格取数(1) 状压DP
- hdu 1565 方格取数(1) (状态压缩dp)
- hdu 1565 方格取数(1)(状态压缩DP)
- hdu 1565 方格取数(1)
- HDU 1565 方格取数(1)(状态压缩DP)
- HDU 1565 方格取数(1)(最大点权独立集)
- HDU 1565 方格取数(1) 黑白染色+最大独立点集
- HDU 1565 方格取数(1)(最小割-Dinic)
- hdu 1565 方格取数(1)(最小割--最大权独立点集)
- HDU 1565 方格取数(1) (状态压缩DP入门题 2)(待更新)
- hdu 1565 方格取数(2)(网络流之最大点权独立集)
- HDOJ/HDU 1565 方格取数(1)
- hdu 1565 方格取数(1) 状态压缩dp
- hdu 1565 方格取数(1) (网络流/状压dp)
- HDU 1565 方格取数(1)
- 【网络流第四弹】最大点权独立集 ——HDU 1565 方格取数(1)
- HDU1565方格取数
- HDU_1565_方格取数(1)
- hdu 1565 方格取数(1)(最小割)