LA4794 Sharing Chocolate

    xiaoxiao2021-12-15  33

    题目

    LA4794 Sharing Chocolate

    题解

    看到数据范围就是状压嘛,,本来觉得复杂度x*3^n太高了会炸结果就是那样。然后发现自己忽略了很多状态是不合法的不会被转移到,所以推荐使用记忆化搜索。然后注意一下,还是输出的时候,特判了之后要么return要么另外输出的时候加else 一个else没看到花了20min,简直了。

    代码

    //QWsin #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=15; const int maxm=100+5; int dp[(1<<maxn)+10][maxm],area[maxn+10]; int Area[(1<<maxn)+10];//集合中选中的对应面积和 int kase=0; inline void print(const char *s){printf("Case %d: %s\n",++kase,s);} int n; int f(int S,int a)//集合,长边 { if(dp[S][a]!=-1) return dp[S][a]; if(Area[S]%a) return 0; int &ans=dp[S][a],b=Area[S]/a; if(a<b) swap(a,b);//由于下方转移时有点事情所以这里要换一下 if(dp[S][a]!=-1) return dp[S][a]; for(int S0=(S-1)&S;S0;S0=(S0-1)&S) { if(f(S0,a)&&f(S^S0,a)) return ans=1;//跟上面呼应,a不一定是长边 if(f(S0,b)&&f(S^S0,b)) return ans=1; } return ans=0; } inline void solve() { memset(dp,-1,sizeof dp); int X,Y,sum=0;scanf("%d%d",&X,&Y); for(int i=0;i<n;++i) { scanf("%d",area+i);sum+=area[i]; int sz=sqrt(area[i]); for(int j=1;j<=sz;++j) if(area[i]%j==0) dp[1<<i][area[i]/j]=1;//先把单个长边处理出来 } for(int S=0;S<(1<<n);++S) { Area[S]=0; for(int i=0;i<n;++i) if(S & (1<<i)) Area[S]+=area[i]; } if(X*Y!=sum) print("No"); else print(f((1<<n)-1,X)?"Yes":"No"); } int main() { while(scanf("%d",&n)==1&&n) solve(); return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-1000163.html

    最新回复(0)