状态压缩
这两个状态压缩,很好玩的啊
#include<bits/stdc++.h> using namespace std; #define LOACL freopen("in","r",stdin);\ freopen("out","w",stdout); typedef long long ll; #define f(i,l,r) for(int i=l;i<=r;++i) #define g(i,l,r) for(int i=l;i>=r;--i) const int mod = 1000000007; const int MOD = 1000000007; int n,m,t,mx,full; ll dp[1009][(1<<11)-1]; int main() { LOACL cin>>n>>m; dp[1][0]=1; t=(1<<m)-1; full=t; mx = (1<<(m<<1))-1; f(i,1,n) { f(k,0,m-1) f(j,0,mx) if((j&(1<<k))==0) { dp[i][ j|(1<<k)|(1<<(k+m)) ] = (dp[i][j|(1<<k)|(1<<(k+m))]+dp[i][j])%mod; if(k<m-1 && (j&(1<<(k+1)))==0) dp[i][j|(1<<k)|(1<<k+1)] = (dp[i][j|(1<<k)|(1<<k+1)] +dp[i][j])%mod; } f(k,0,mx) if(k&t==t) dp[i+1][k>>m]=dp[i][k]; } cout<<dp[n][t]; return 0; }
#include<bits/stdc++.h> using namespace std; #define LOACL freopen("in","r",stdin);\ freopen("out","w",stdout); typedef long long ll; #define f(i,j,k) for (int i=j;i<=k;i++) #define g(i,j,k) for (int i=j;i>=k;i--) const int sz = 1e7+5; #define low(x) (x)&(-x) int n,m,q,t ; int w[1<<18] ,state[1<<9],cn[1<<9]; int dp [1009][1<<9]; void init() { int k = 1<<(m-1); for(int i=0;i<k;i++) { int tmp=i; int ans =0; while(tmp) { tmp-=low(tmp); ans++; } cn[i]=ans; if(ans<=q) state[++t]=i; } } int main() { cin>>n>>m>>q; for(int i=1;i<=n;i++) cin>>w[i]; if(m==q) { int ans= 0; for(int i=1;i<=n;i++) ans+=w[i]; cout<<ans<<endl; return 0; } init(); int k= 1<<(m-2); dp[1][k]=w[1]; for(int i =2;i<=n;i++) { for(int j=1;j<=t;j++) { int nxt = state[j]>>1; if(cn[state[j]]<q) dp[i][nxt+k]=max(dp[i][nxt+k],dp[i-1][state[j]]+w[i]); dp[i][nxt]=max(dp[i-1][state[j]],dp[i][nxt]); } } int ans=0; for(int i=1;i<=t;i++) { ans =max(ans,dp[n][state[i]]); } cout<<ans<<endl; return 0; }
我说一下hiho2
dp[i][j]============> 第i 行 状态 j 1-m位 为第一行 m+1-2m 为第二行 这样只要一顿 & | 就可以 得出答案
不需要 剪枝 很爽的
不摸着石头过河,难道要在温柔乡睡到天昏地暗。