poj1185 [NOI2001炮兵阵地]

本文介绍了一种使用状压动态规划(State Sizing Dynamic Programming)解决排列组合问题的方法,通过状态压缩优化空间复杂度,同时保持时间复杂度在合理范围内。详细解释了如何在给定条件下使用此技术来解决特定问题,并提供了代码实现和实例分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

状压DP

本来如果考虑所有情况应该开hh[n][2^10][2^10]表示i行在i-1的状态为j,i-2的状态为k的最大个数

但是由于每行中的人互相限制所以在m=10时只有60种情况

空间就可以满足,时间也可以满足了

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<string>
 7 #include<cmath>
 8 #include<ctime>
 9 #include<queue>
10 #include<stack>
11 #include<map>
12 #include<set>
13 #define rre(i,r,l) for(int i=(r);i>=(l);i--)
14 #define re(i,l,r) for(int i=(l);i<=(r);i++)
15 #define Clear(a,b) memset(a,b,sizeof(a))
16 #define inout(x) printf("%d",(x))
17 #define douin(x) scanf("%lf",&x)
18 #define strin(x) scanf("%s",(x))
19 #define LLin(x) scanf("%lld",&x)
20 #define op operator
21 #define CSC main
22 typedef unsigned long long ULL;
23 typedef const int cint;
24 typedef long long LL;
25 using namespace std;
26 void inin(int &ret)
27 {
28     ret=0;int f=0;char ch=getchar();
29     while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
30     while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar();
31     ret=f?-ret:ret;
32 }
33 int s[66],x,shu[66];
34 int n,m,a[111];
35 int hh[111][66][66];
36 char ss[111][11];
37 void dfs(int xx,int ss,int sh)
38 {
39     if(xx>m)
40     {
41         s[++x]=ss;shu[x]=sh;
42         return ;
43     }
44     dfs(xx+1,ss,sh);
45     dfs(xx+3,ss|(1<<xx),sh+1);
46 }
47 int CSC()
48 {
49     freopen("in.in","r",stdin);
50     freopen("out.out","w",stdout);
51     inin(n),inin(m);
52     dfs(1,0,0);
53     re(i,1,n)
54     {
55         strin(ss[i]+1);
56         re(j,1,m)if(ss[i][j]=='H')a[i]|=(1<<j);
57     }
58     re(i,1,x)if(!(a[1]&s[i]))
59         hh[1][i][0]=shu[i];
60     re(i,1,x)
61         if(!(a[2]&s[i]))
62         re(j,1,x)
63             if(!(s[i]&s[j]))
64             hh[2][i][j]=max(hh[2][i][j],hh[1][j][0]+shu[i]);
65     re(r,3,n)
66         re(i,1,x)if(!(s[i]&a[r]))
67         re(j,1,x)if(!(s[j]&a[r-1]))if(!(s[i]&s[j]))
68             re(k,1,x)if(!(s[k]&a[r-2]))if(!(s[j]&s[k]))if(!(s[i]&s[k]))
69                 hh[r][i][j]=max(hh[r][i][j],hh[r-1][j][k]+shu[i]);
70     int ans=0;
71     re(i,1,x)re(j,1,x)
72         ans=max(ans,hh[n][i][j]);
73     printf("%d",ans);
74     return 0;
75 }

 

转载于:https://www.cnblogs.com/HugeGun/p/5216774.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值