11.10模拟

 

 

得了92.5分。辣鸡。懒惰的我不想去掉红字了,凑合着看吧。

 

 

 

 

 题解:二分答案。

        数据类型决定成败。30->85->100.

 

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define N 200100
#define ll long long 
using namespace std;
#ifdef unix
#define LL "%lld"
#else
#define LL "%I64d"
#endif
ll n,m;
ll k;
ll ans;
ll a[N],b[N];
void erfen(ll l,ll r)
{
    if (l>r) return ;
    ll mid=(l+r)>>1;
    ll p(m),sum(0);
    for (ll i=1;i<=n;i++)
      {
           while (p>0&&a[i]*b[p]>mid) p--;
           sum+=p;
      }
    if (sum>=k) ans=mid,erfen(l,mid-1);
    else erfen(mid+1,r);
}
int main()
{
    freopen("number.in","r",stdin);
    freopen("number.out","w",stdout);
    scanf(LL LL LL,&n,&m,&k);
    for (ll i=1;i<=n;i++) scanf(LL,&a[i]);
    for (ll i=1;i<=m;i++) scanf(LL,&b[i]);
    sort(a+1,a+n+1);
    sort(b+1,b+m+1);
    erfen(0,a[n]*b[m]);
    cout<<ans<<endl;
    fclose(stdin);
    fclose(stdout);
    return 0;
}
二分

 

 

 

 

 

 题解:考试的时候想用搜索做,写min函数的时候定义成了bool型,,找了半天错误,咋就是返回1.然后还是可爱的小qg提醒,才知道要处理环。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<ctime>
#define N 10010
#define M 100010
#define ll long long
using namespace std;
int n,m,cnt(0);
ll v[N];
int num[N][2];
ll minn;
bool f[N]={0},vis[N];
struct node
{
    int z;
    int x,y;
    
}a[M];
int min(ll x,ll y)
{
    if (x<y) return x;
    else return y;
}
ll dfs(int ki)
{
    if (clock()>900) 
      {
           printf("%d\n",f[1]);
           fclose(stdin);
           fclose(stdout);
           return 0;
      }
    if (vis[ki]) return v[ki];
    if (!f[ki]) return v[ki];
    for (int i=num[ki][0];i<=num[ki][1];i++)
      {
          vis[ki]=1;
          v[ki]=min(v[ki],dfs(a[i].x)+dfs(a[i].y));     
          vis[ki]=0;
      }  
    f[ki]=1;                
    return v[ki];
}
bool cmp(node c,node d)
{
    if (c.z<d.z) return 1;
    else return 0;
}
int main()
{
    freopen("dwarf.in","r",stdin);
    freopen("dwarf.out","w",stdout);
    
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++) scanf("%lld",&v[i]);
    for (int i=1;i<=m;i++)
      scanf("%d%d%d",&a[i].z,&a[i].x,&a[i].y);
    sort(a+1,a+m+1,cmp);
    for (int i=1,k;i<=m;i++)
      {
           k=a[i].z;
           if (!f[k]) f[k]=1,num[a[i-1].z][1]=i-1,num[k][0]=i;
      }
    num[a[m].z][1]=m;
    minn=dfs(1);
    cout<<minn<<endl;
    
    fclose(stdin);
    fclose(stdout);
    
    return 0;
}
考场上辣鸡的超时搜索(72.5)

 题解:看了正解之后,哦豁,好神奇,还能用spfa求。由于x,y能合成v,所以x—>v,距离是y;y->v,距离是x。然后跑最短路,这个最短距离就是得到物品i的最小代价。输出到1的最短距离即为解。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 100010
#define ll long long
using namespace std;
int n,m,Head(0),tail(0),num(0);
int vi[N],dis[N],head[N]={0},team[N];
bool f[N]={0};
struct node
{
    int v,t,pre;
}e[N*2];
void add(int to,int from,int dis)
{
    e[++num].v=to;
    e[num].t=dis;
    e[num].pre=head[from];
    head[from]=num;
}
void spfa()
{
    for (int i=1;i<=n;i++)
      {
           dis[i]=vi[i];
           team[++tail]=i;
           f[i]=1;
      }
    while (Head<=tail)
      {
           int k=team[++Head];
           f[k]=0;
           for (int i=head[k];i;i=e[i].pre)
             {
                   int v=e[i].v;
                   if (dis[v]>dis[k]+dis[e[i].t])
                     {
                         dis[v]=dis[k]+dis[e[i].t];
                         if (f[v]==0)
                           {
                              f[v]=1;
                         team[++tail]=v;    
                      }
                }
             }
      }
      
}
int main()
{
    freopen("dwarf.in","r",stdin);
    freopen("dwarf.out","w",stdout);
    
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++) scanf("%d",&vi[i]);
    for (int i=1;i<=m;i++)
      {
           int v,x,y;
           scanf("%d%d%d",&v,&x,&y);
           add(v,x,y);
           add(v,y,x);
      }
    spfa();
    printf("%d\n",dis[1]);
    
    fclose(stdin);
    fclose(stdout);
    
    return 0;
}
神奇的spfa

 

 

题解:神奇的多重背包。详情请见博客大犇lemon

 

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define N 100100
using namespace std;
int n,V(0),num(0),ans(0);
int a[N],b[N],c[N],d[N],w[N],v[N],f[N];
void xx(int wi,int vi,int ci)//二分制优化 
{
    for (int i=1;i<=ci;i*=2)
      {
           ci-=i;
           v[++num]=vi*i;
           w[num]=wi*i;
      }
    if (ci) v[++num]=vi*ci,w[num]=wi*ci;
}
int main()
{
    freopen("abcd.in","r",stdin);
    freopen("abcd.out","w",stdout);
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
      {
           scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);//c[i]体积,d[i]价值,b[i]最大数量 
           b[i]-=a[i];
           V-=a[i]*c[i];
           ans+=a[i]*d[i];//由于价值实在基于-a[i]的前提下,因此最后要加上减去的价值。 
      }
    for (int i=1;i<=n;i++) xx(d[i],c[i],b[i]);
    for (int i=1;i<=num;i++) f[i]=-0x7fffffff/3;
    for (int i=1;i<=num;i++)
      for (int j=V;j>=v[i];j--)
        f[j]=max(f[j],f[j-v[i]]+w[i]); 
        
    cout<<f[V]+ans<<endl;
    
    fclose(stdin);
    fclose(stdout);
}
多重背包

 

posted @ 2016-11-10 21:20  外婆桥  阅读(163)  评论(0编辑  收藏  举报