• 小木棍 && 愤怒的小鸟


    小木棍

    题目描述

    乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050。

    现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。

    给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。

    输入输出格式

    输入格式:

    共二行。

    第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤65N65

    (管理员注:要把超过5050的长度自觉过滤掉,坑了很多人了!)

    第二行为NN个用空个隔开的正整数,表示NN根小木棍的长度。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<vector>
      7 #include<queue>
      8 #include<map>
      9 #include<set>
     10 #include<stack>
     11 using namespace std;
     12 const int maxn=100007;
     13 const int INF=0x7f7f7f7f;
     14 int n,m,sum,stp,ans=INF,req;
     15 int len[maxn],s[maxn],nxt[maxn];
     16 bool is[maxn],usd[maxn],bj; 
     17 void gettable(){
     18   for(int i=2;i<=sqrt(sum);i++){
     19     if(sum%i==0){
     20       if(i>=len[1]) s[++stp]=i;
     21       if(i!=(sum/i)) if(sum/i>=len[1]) s[++stp]=sum/i;
     22     }
     23   }
     24 }
     25 bool cmp(int a,int b){
     26   return a>b;
     27 }
     28 /*bool dfs(int now,int st,int lft){
     29   bool flg=false;
     30   if(lft==0&&st==sum/req) return true;
     31   if(lft==0){
     32     int i;
     33     for(i=1;i<=n;i++){
     34       if(!usd[i]){usd[i]=true;flg=true;break;}
     35     }
     36     if(flg) dfs(i,st+1,req-len[i]);
     37   }
     38   bool flag=false;
     39   for(int i=now+1;i<=n;i++){
     40     if(usd[i]) continue;
     41     if(lft>=len[i]){
     42       usd[i]=true;flag=true;
     43       if(dfs(i,st,lft-len[i])) return true;
     44       else return false;
     45       usd[i]=false;
     46     }
     47   }
     48   if(!flag) return false;
     49 }*/
     50 void dfs(int k,int last,int rest){
     51   int i,j;
     52   if(rest==0){
     53     if(k==(sum/req)){bj=1;return;}
     54     for(i=1;i<=n;i++)
     55       if(!usd[i]){usd[i]=true;break;}
     56     dfs(k+1,i,req-len[i]);
     57     usd[i]=false;
     58     if(bj) return;
     59   }
     60   int l=last+1, r=n, mid;
     61   while(l<=r){
     62     mid=(l+r)/2;
     63     if(len[mid]<=rest) r=mid-1;
     64     else l=mid+1;
     65   }
     66   for(i=l;i<=n;i++){
     67     if(!usd[i]){ 
     68       usd[i]=1;
     69       dfs(k,i,rest-len[i]);
     70       usd[i]=0;
     71       if(bj) return;   
     72       if(rest==len[i]) return; 
     73       i=nxt[i];
     74       if(i==n) return;
     75     }
     76   }
     77 }
     78 int main(){
     79   cin>>m;
     80   for(int i=1;i<=m;i++){
     81     int a;cin>>a;if(a>50) continue;
     82     len[++n]=a;sum+=len[n];
     83   }
     84   sort(len+1,len+n+1,cmp);
     85   gettable();
     86   sort(s+1,s+n+1,cmp);
     87   nxt[n]=n;
     88   for(int i=n-1;i>=1;i--){
     89     if(len[i]==len[i+1]) nxt[i]=nxt[i+1];
     90     else nxt[i]=i;
     91   }
     92   for(int i=1;i<=stp;i++){
     93       if(is[i]) continue;
     94       memset(usd,false,sizeof(usd)); 
     95       bj=false;usd[1]=true;req=s[i];
     96     dfs(1,1,req-len[1]);
     97     if(!bj){
     98       for(int j=i+1;j<=stp;j++){
     99         if(s[i]%s[j]==0) is[j]=true;
    100       }
    101     }
    102     else ans=min(ans,s[i]);  
    103   }
    104   if(ans==INF) cout<<sum<<endl;
    105   else cout<<ans<<endl;
    106 } 

     愤怒的小鸟

    这样搜会T一半的点:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 typedef long double dd;
     8 const int maxn=27;
     9 const int INF=0x7f7f7f7f;
    10 const dd eps=1e-8;
    11 int t,n,m,ans;
    12 dd x[maxn],y[maxn];
    13 bool flag,bflg[maxn][maxn];
    14 bool usd[maxn],busd[maxn][maxn][maxn];
    15 dd geta(dd x1,dd x2,dd y1,dd y2){
    16   dd ret;
    17   ret=(x1*y2-y1*x2)/((x1*x2)*(x2-x1));
    18   return ret;
    19 }
    20 dd getb(dd x1,dd x2,dd y1,dd y2){
    21   dd ret;
    22   ret=(y2*x1*x1-y1*x2*x2)/((x1*x2)*(x1-x2));
    23   return ret;
    24 }
    25 void cpy(int zhu,int niao){
    26   for(int i=1;i<=n;i++)
    27     busd[zhu][niao][i]=usd[i];
    28   bflg[zhu][niao]=flag;
    29 }
    30 void recpy(int zhu,int niao){
    31   for(int i=1;i<=n;i++)
    32     usd[i]=busd[zhu][niao][i];
    33   flag=bflg[zhu][niao];
    34 }
    35 bool zai(dd x,dd y,dd a,dd b){
    36   dd tmp=a*x*x+b*x;
    37   if(fabs(tmp-y)<eps) return true;
    38   return false; 
    39 }
    40 void dfs(int zhu,int niao){
    41   if(niao>ans||niao>n) return;
    42   if(m==1){
    43       int tmp;
    44     if(n%3!=0) tmp=n/3+1+1;
    45     else tmp=n/3+1;
    46     if(niao>tmp) return;
    47   }
    48   if(m==2){if(zhu<(n/3)&&!flag) return;}
    49   if(zhu==0){
    50     if(m==0) ans=min(ans,niao);
    51     if(m==1) ans=min(ans,niao);
    52     if(m==2){
    53       if(flag) ans=min(ans,niao);
    54     }
    55   }
    56   for(int i=1;i<=n;i++){
    57       if(usd[i]) continue;
    58       bool vis=false;
    59     for(int j=i+1;j<=n;j++){
    60       if(!usd[i]&&!usd[j]){
    61         dd a=geta(x[i],x[j],y[i],y[j]);
    62         dd b=getb(x[i],x[j],y[i],y[j]);
    63         if(a<=0){
    64           int tmp=zhu;
    65           cpy(zhu,niao);
    66           for(int k=1;k<=n;k++){
    67               if(usd[k]) continue;
    68             if(zai(x[k],y[k],a,b)){
    69               usd[k]=true;tmp--;
    70             }
    71           }
    72           if((zhu-tmp)>=(n/3)) flag=true;
    73           vis=true;dfs(tmp,niao+1);
    74           recpy(zhu,niao);
    75         }
    76       }
    77     }
    78     if(!vis){
    79       usd[i]=true;dfs(zhu-1,niao+1);
    80       usd[i]=false;
    81     }
    82   }
    83 }
    84 int main(){
    85   //freopen("a.in","r",stdin);
    86   scanf("%d",&t);
    87   while(t--){
    88       ans=INF;flag=false;memset(usd,false,sizeof(usd));
    89     memset(x,0,sizeof(x));memset(y,0,sizeof(y));
    90     scanf("%d%d",&n,&m);
    91     for(int i=1;i<=n;i++) cin>>x[i]>>y[i];
    92     dfs(n,0);if(ans==INF) ans=n;
    93     printf("%d
    ",ans);
    94   }
    95 } 

    这样搜比较好:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 typedef double dd;
     8 const int maxn=27;
     9 const int INF=0x7f7f7f7f;
    10 const dd eps=1e-8;
    11 int t,n,m,ans;
    12 dd x[maxn],y[maxn],ai[maxn],bi[maxn],xi[maxn],yi[maxn];
    13 bool zai(dd x,dd y,dd a,dd b){
    14   dd tmp=a*x*x+b*x;
    15   if(fabs(tmp-y)<eps) return true;
    16   return false; 
    17 }
    18 bool tong(dd x,dd y){
    19   return fabs(x-y)<eps;
    20 }
    21 dd geta(dd x1,dd x2,dd y1,dd y2){
    22   dd ret;
    23   ret=(x1*y2-y1*x2)/((x1*x2)*(x2-x1));
    24   return ret;
    25 }
    26 dd getb(dd x1,dd x2,dd y1,dd y2){
    27   dd ret;
    28   ret=(y2*x1*x1-y1*x2*x2)/((x1*x2)*(x1-x2));
    29   return ret;
    30 }
    31 void dfs(int z,int u,int v){
    32   if(u+v>=ans) return;
    33   if(z>n){ans=min(ans,u+v);return;}
    34   bool vis=false;
    35   for(int i=1;i<=u;i++){
    36     if(zai(x[z],y[z],ai[i],bi[i])){
    37       vis=true;dfs(z+1,u,v);break;
    38     }
    39   }
    40   if(!vis){
    41     for(int i=1;i<=v;i++){
    42       dd xx=xi[i];dd yy=yi[i];
    43       if(tong(xx,x[z])) continue;
    44       dd a=geta(x[z],xx,y[z],yy);
    45       dd b=getb(x[z],xx,y[z],yy);
    46       if(a<0){
    47         ai[u+1]=a;bi[u+1]=b;
    48         dd tm=xi[i];dd tp=yi[i];
    49         for(int j=i;j<v;j++){
    50           xi[j]=xi[j+1];yi[j]=yi[j+1];
    51         }
    52         dfs(z+1,u+1,v-1);
    53         for(int j=v;j>i;j--){
    54           xi[j]=xi[j-1];yi[j]=yi[j-1];
    55         }
    56         xi[i]=tm;yi[i]=tp;
    57       }
    58     }
    59     xi[v+1]=x[z];yi[v+1]=y[z];
    60     dfs(z+1,u,v+1);
    61   }
    62 }
    63 int main(){
    64   //freopen("a.in","r",stdin); 
    65   scanf("%d",&t);
    66   while(t--){
    67     scanf("%d%d",&n,&m);ans=INF;
    68     memset(ai,0,sizeof(ai));memset(bi,0,sizeof(bi));
    69     memset(xi,0,sizeof(xi));memset(yi,0,sizeof(yi)); 
    70     for(int i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]);
    71     dfs(1,0,0);printf("%d
    ",ans);
    72   }
    73 }

     正解是状压:

  • 相关阅读:
    【BZOJ 3098】 Hash Killer II
    【BZOJ 1189】[HNOI2007]紧急疏散evacuate
    【BZOJ 1088】 [SCOI2005]扫雷Mine
    【BZOJ 1821】 [JSOI2010]Group 部落划分 Group
    【BZOJ 1013】 [JSOI2008]球形空间产生器sphere
    【BZOJ 1084】[SCOI2005]最大子矩阵
    【BZOJ 1085】 [SCOI2005]骑士精神
    JNday6-pm
    JNday6-am
    JNday5-pm
  • 原文地址:https://www.cnblogs.com/lcan/p/9885374.html
Copyright © 2020-2023  润新知