麦香牛块洛谷传送门,麦香牛块USACO传送门,篱笆回路洛谷传送门,篱笆回路USACO传送门
洛谷 2737 麦香牛块
分析
首先如果包装总GCD不为1,显然没有上界
然后这个答案如果存在必然满足在一个范围内,
可以推结论得到上界为\(max*(max-1)\)(好像是反证法)
然后就可以用完全背包求解啦,
但是为了推广\(\text{STL::bitset}O(\frac{n*maxlogLIMIT}{32})\)的做法
所以我就写了跑得更慢的做法T^T
代码
/* ID:lemondi1 LANG:C++ TASK:nuggets */ #include <cstdio> #include <algorithm> #include <bitset> #define rr register using namespace std; const int N=65300; bitset<N>dp; int n,a[11],G,ans,lim; inline signed gcd(int a,int b){return b?gcd(b,a%b):a;} signed main(){ freopen("nuggets.in","r",stdin); freopen("nuggets.out","w",stdout); scanf("%d",&n); for (rr int i=1;i<=n;++i){ scanf("%d",&a[i]); G=gcd(G,a[i]); } if (G!=1) return !printf("0\n"); dp[0]=1,sort(a+1,a+1+n),lim=a[n]*(a[n]-1); for (rr int i=1;i<=n;++i) for (rr int j=a[i];j<=lim;j<<=1) dp|=dp<<j; dp[0]=0; for (rr int i=a[n]*(a[n]-1);~i;--i) if (!dp[i]) return !printf("%d\n",i); }
洛谷 2738 篱笆回路
分析
显然是求最小环,数据小用\(\text{FLOYD}\)解决
但是建图是关键,考虑用哈希存下某篱笆某一边所有可连的篱笆(包括它自己)
这样就可以加点了
代码
/* ID:lemondi1 LANG:C++ TASK:fence6 */ #include <cstdio> #include <cctype> #include <algorithm> #include <cstring> #include <map> #define rr register using namespace std; typedef unsigned uit; map<uit,int>uk; int d[101][101],dis[101][101],n,ans,a[11]; inline signed iut(){ rr int ans=0; rr char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar(); return ans; } signed main(){ freopen("fence6.in","r",stdin); freopen("fence6.out","w",stdout); memset(dis,42,sizeof(dis)), memset(d,42,sizeof(d)),ans=d[0][0]; for (rr int Test=iut();Test;--Test){ rr int Num=iut(),Len=iut(),X[2]; rr int nn[2]={iut(),iut()},Tot; for (rr int j=0;j<2;++j){ a[Tot=1]=Num; for (;nn[j];--nn[j]) a[++Tot]=iut(); sort(a+1,a+1+Tot); rr uit h=a[1]; for (rr int i=2;i<=Tot;++i) h=h*137+a[i]; if (!uk[h]) uk[h]=++n; X[j]=uk[h]; } dis[X[0]][X[1]]=d[X[0]][X[1]]=Len; dis[X[1]][X[0]]=d[X[1]][X[0]]=Len; } for (rr int k=1;k<=n;++k){ for (rr int i=1;i<k-1;++i) for (rr int j=i+1;j<k;++j) ans=min(ans,dis[i][j]+d[i][k]+d[j][k]); for (rr int i=1;i<=n;++i) for (rr int j=1;j<=n;++j) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); } return !printf("%d\n",ans); }
来源:https://www.cnblogs.com/Spare-No-Effort/p/12386342.html