• cj 练习


    一个劫匪带着一个可装m重量的超大背包去抢银行,银行有n个大箱子,第i个箱子里有i个重量为wi,价值为ci的大钻石,问该劫匪抢走钻石的最大价值
    Input
    第一行为一整数T表示用例组数,每组用例第一行为两个整数n和m分别表示钻石个数和背包可装钻石重量上限,第二行为n个整数wi表示第i箱子中每颗钻石的重量,第三行为n个整数ci表示第i箱子中每颗钻石的价值。
    数据范围:(1<=T<=74,1<=n<=15,1<=wi,ci,m<=1e9)
    Output
    对于每组用例,输出该劫匪带走钻石的最大价值
    Sample Input
    2
    2 4
    3 2
    5 3
    3 100
    4 7 1
    5 9 2
    Sample Output
    6
    29

     思路:完全背包问题,可用DFS大法解,用weight表示当前重量,用ans表示劫匪能偷走最大价值,再递归调用求解,每次动态求出当前(局部)可偷出的最大价值,再算出整体的最大价值,但WA了,一分没得

    参考代码(WA)

    #include <iostream>
    using namespace std;
    int w[16],v[16],k[16];
    int n,m,time;
    int ans,sum[16];
    void turn(int &x,int &y)
    {
    int temp;
    temp=x;
    x=y;
    y=temp;
    }
    void sort()
    {
    int i,j,temp;
    for(int i=1;i<n;i++)
    for(int j=i+1;j<=n;j++)
    if(v[i]*w[j]<v[j]*w[i])
    {
    turn(w[i],w[j]);
    turn(v[i],v[j]);
    turn(k[i],k[j]);
    }
    }
    void put(int x)
    {
    if (ans<x) ans=x;
    }
    void dfs(int left,int x,int value)
    {
    int i;
    if (x>n)
    {
    put(value);
    return;
    }
    if(time==2147483647)
    return;
    double cost;
    cost=value+((double)left)/w[x]*v[x];
    if(cost<ans)
    return;
    cost=value+sum[n]-sum[x-1];
    if(cost<ans)
    return;
    for(int i=k[x];i>=0;i--)
    if(left>=i*w[x])
    {
    time++;
    dfs(left-i*w[x],x+1,value+i*v[x]);
    }
    }
    int main()
    {
    freopen("robbery.in","r",stdin);
    freopen("robbery.out","w",stdout);
    int i,t;
    int weight;
    cin>>t;
    for(int i=1;i<=t;i++)
    {
    cin>>n>>m;
    weight=0;
    for(int j=1;j<=n;j++)
    {
    cin>>w[j];
    weight+=w[j]*i;
    }
    for(int j=1;j<=n;j++)
    {
    cin>>v[j];
    k[j]=j;
    }
    sort();
    sum[0]=0;
    for(int j=1;j<=n;j++)
    sum[j]=sum[j-1]+v[j]*k[j];
    ans=0;
    int mm=m;
    for(int i=1;i<=n;i++)
    if(mm>=w[i])
    if(mm>=w[i]*k[i])
    {
    ans+=v[i]*k[i];
    mm-=w[i]*k[i];
    }
    else
    {
    ans+=(mm/w[i])*v[i];
    mm=mm-w[i]*(mm/w[i]);
    }
    time=0;
    if(weight>m)
    dfs(m,1,0);
    else
    ans=sum[n];
    cout<<ans;
    }
    return 0;
    }

    2、egypt

     Description
    在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数。 如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的。 对于一个分数a/b,表示方法有很多种,但是哪种最好呢? 首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越 好。 如:

    19/45=1/3 + 1/12 + 1/180

    19/45=1/3 + 1/15 + 1/45

    19/45=1/3 + 1/18 + 1/30

    19/45=1/4 + 1/6 + 1/180

    19/45=1/5 + 1/6 + 1/18.

    最好的是最后一种,因为1/18比1/180,1/45,1/30,1/180都大。 给出a,b(0 < a < b < 1000),编程计算最好的表达方式。
    输入描述 Input Description
    a b
    输出描述 Output Description
    若干个数,自小到大排列,依次是单位分数的分母。
    样例输入 Sample Input
    19 45
    样例输出 Sample Output
    5 6 18

    思路:根据题目意思,将a/b分层,第一层1/10,第二层10-100-----再定义DFS函数求解,开始只得了70分,后来发现(0 < a < b < 1000)的条件后,发现调用函数时会超时,把int改为long long 即可AC

    参考代码:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    int depth=0,min1,aijifenshu1;
    int ans[110],out[110];
    void dfs(int a,int b,int x)
    {
    if(depth>=aijifenshu1||x>=min1)
    return;
    if(b%a==0)
    {
    b/=a;
    if(b<x||b>=min1)
    return;
    ans[depth]=b;
    min1=b;
    memcpy(out,ans,(depth+1)*sizeof(int));
    return;
    }
    else
    {
    if(depth>=aijifenshu1-1)
    return ;
    while(a*x<=b&&x<min1)
    {
    x++;
    }
    while(x<min1)
    {
    if(a*x>=b*(aijifenshu1-depth))
    break;
    ans[depth]=x;
    depth++;
    dfs(a*x-b,b*x,x+1);
    depth--;
    x++;
    }
    }
    return ;
    }
    int main()
    {
    freopen("egypt.in","r",stdin);
    freopen("egypt.out","w",stdout);
    int a,b;
    cin>>a>>b;
    min1=2147483647;
    for(aijifenshu1=1;aijifenshu1<=110;aijifenshu1++)
    {
    dfs(a,b,1);
    if(min1<2147483647)
    break;
    }
    for(int k=0;k<aijifenshu1-1;k++)
    cout<<out[k]<<" ";
    cout<<out[aijifenshu1-1];
    return 0;
    }

  • 相关阅读:
    驾照更换说明
    批处理创建快捷方式
    AC中保存数据与查询数据
    logger日志模块
    如何将python脚本转化为exe
    numpy学习
    request是个什么东西
    django的test文件的使用方式
    高频正则表达式
    dir 的作用
  • 原文地址:https://www.cnblogs.com/jr-ag/p/8641893.html
Copyright © 2020-2023  润新知