• 110.科技庄园(多重背包)(未结题)


    3556 科技庄园

     

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 黄金 Gold
    题目描述 Description

    Life是codevs的用户,他是一个道德极高的用户,他积极贯彻党的十八大精神,积极走可持续发展道路,在他的不屑努力下STN终于决定让他在一片闲杂地里种桃,以亲身实践种田的乐趣,厉行节约,告诉人们节约的重要性!

    春华秋实,在这个金秋的季节,Life带者他的宠物——PFT到了他的试验田,当他看见自己的辛勤成果时,心里是那个高兴啊!

    这时Life对他的宠物PFT说:“你想不想吃桃啊?”

    PFT兴奋的说:“好啊!”

    Life说:“好吧,但是我只给你一定的时间,你必须在规定的时间之内回到我面前,否则你摘的桃都要归我吃!”

    PFT思考了一会,最终答应了!

    由于PFT的数学不好!它并不知道怎样才能在规定的时间获得最大的价值,但你是一个好心人,如果你帮助它,你的RP一定会暴涨的!

    对于这个可以RP暴涨机会,你一定不会错过的是不是?

    由于PFT不是机器人,所以他的体力并不是无限的,他不想摘很多的桃以至体力为0,而白白把桃给Life。同时PFT每次只能摘一棵桃树,每棵桃树都可以摘K次(对于同一棵桃每次摘的桃数相同)。每次摘完后都要返回出发点(PFT一次拿不了很多)即Life的所在地(0,0){试验田左上角的桃坐标是(1,1)}。

    PFT每秒只能移动一个单位,每移动一个单位耗费体力1(摘取不花费时间和体力,但只限上下左右移动)。


    输入描述 Input Description

    第一行:四个数为N,M,TI,A 分别表示试验田的长和宽,Life给PFT的时间,和PFT的体力。

    下面一个N行M列的矩阵桃田。表示每次每棵桃树上能摘的桃数。

    接下来N行M列的矩阵,表示每棵桃最多可以采摘的次数K。


    输出描述 Output Description

    一个数:PFT可以获得的最大的桃个数。

    样例输入 Sample Input

    4 4 13 20

    10 0 0 0

    0 0 10 0

    0 0 10 0

    0 0 0 0

    1 0 0 0

    0 0 2 0

    0 0 4 0

    0 0 0 0


    样例输出 Sample Output

    10

    数据范围及提示 Data Size & Hint

    【样例解释】

    可以摘到1次(1,1)或1次(2,3)或1次(3,3),体力和时间不满足再摘桃了。


    【数据范围】

    对于M N TI A

    10<=30%<=50

    10<=100%<=100

    对于K

    10<=100%<=100

    保证结果在longint范围内


    分类标签 Tags 点此展开 

      代码:3个点没过
         方法一:多重背包,
    #include< iostream >
    #include< cstdio >
    using namespace std;
    int taosum=0,n,m,tim,tili;
    long long int f[1001];
    struct Tao{
     long long int x,y;
     long long int sum,cs;
    };
    Tao tao[2500001];
    int t=0;
    void input()
    {
     int k;
     scanf("%d%d%d%d",&n,&m,&tim,&tili);
     for(int i=1;i<=n;++i)//x
       for(int j=1;j<=m;++j)//y
       {
        scanf("%d",&k);
        if(k!=0)
        {
         ++t;
         tao[t].x=i;
         tao[t].y=j;
         tao[t].sum=k;
        }
       }
     t=0;
     for(int i=1;i<=n;++i)
       for(int j=1;j<=m;++j)
       {
        scanf("%d",&k);
        if(k!=0)
        {
         t++;
         tao[t].cs=k;
        }
       }
       int p=t;
     for(int i=1;i<=p;++i)
     {
      while(tao[i].cs!=1)
      {
       tao[i].cs--;
       t++;
       tao[t].x=tao[i].x;
       tao[t].y=tao[i].y;
       tao[t].sum=tao[i].sum;
      }
     }
    }
    int main()
    {
     input();
     for(int i=1;i<=t;++i)
       for(int j=min(tim,tili);j>(tao[i].x+tao[i].y)*2;--j)
         f[j]=max(f[j],f[j-2*tao[i].x-2*tao[i].y]+tao[i].sum);
     printf("%d ",f[min(tili,tim)]);
     return 0;
    }
    方法二:二进制分法:
    #include< iostream >
    #include< cstdio >
    using namespace std;
    int taosum=0,n,m,tim,tili;
    long long int f[200001];
    struct Tao{
     long long int x,y;
     long long int sum;
    };
    Tao tao[3600010];
    int t=0;
    void input()
    {
     int k;
     scanf("%d%d%d%d",&n,&m,&tim,&tili);
     for(int i=1;i<=n;++i)//x
       for(int j=1;j<=m;++j)//y
       {
        scanf("%d",&k);
        if(k!=0)
        {
         ++t;
         tao[t].x=i;
         tao[t].y=j;
         tao[t].sum=k;
        }
       }
     int p=0;
     for(int i=1;i<=n;++i)
       for(int j=1;j<=m;++j)
       {
        scanf("%d",&k);//ci shu
        if(k!=0&&tao[p+1].sum!=0)
        {
         p++;
      for(int i=1;i<=k;i*=2)
      {
       if(i==1)
       {
       tao[p].x=tao[p].x*i;
       tao[p].y=tao[p].y*i;
       tao[p].sum=tao[p].sum*i;
       k-=i;
       continue;
       }
       ++t;
       tao[t].x=tao[p].x*i;
       tao[t].y=tao[p].y*i;
       tao[t].sum=tao[p].sum*i;
       k-=i;
       
      }
      if(k>0)
      {
       ++t;
       tao[t].x=tao[p].x*k;
       tao[t].y=tao[p].y*k;
       tao[t].sum=tao[p].sum*k;
      }
      }
      
       }
      
    }
    int main()
    {
     
     input();
     int VV=min(tim,tili-1);
     for(int i=1;i<=t;++i)
       for(int j=VV;j>=(tao[i].x+tao[i].y)*2;--j)
         f[j]=max(f[j],f[j-2*tao[i].x-2*tao[i].y]+tao[i].sum);
     printf("%d ",f[VV]);
     return 0;
    }
    方法三:没过,不分解,01背包再加一层循环
    代码:
     #include< iostream >
    #include< cstdio >
    using namespace std;
    int taosum=0,n,m,tim,tili;
    long long int f[1001];
    struct Tao{
     long long int x,y;
     long long int sum,cs;
    };
    Tao tao[3600010];
    int t=0;
    void input()
    {
     int k;
     scanf("%d%d%d%d",&n,&m,&tim,&tili);
     for(int i=1;i<=n;++i)//x
       for(int j=1;j<=m;++j)//y
       {
        scanf("%d",&k);
        if(k!=0)
        {
         ++t;
         tao[t].x=i;
         tao[t].y=j;
         tao[t].sum=k;
        }
       }
     t=0;
     for(int i=1;i<=n;++i)
       for(int j=1;j<=m;++j)
       {
        scanf("%d",&k);
        if(k!=0)
        {
         t++;
         tao[t].cs=k;
        }
       }
    }
    int main()
    {
     input();
     for(int i=1;i<=t;++i)
       for(int l=1;l<=tao[i].cs;++l)
         for(int j=min(tim,tili-1);j>=(tao[i].x+tao[i].y)*2;--j)
         f[j]=max(f[j],f[j-2*tao[i].x-2*tao[i].y]+tao[i].sum);
     printf("%d ",f[min(tili-1,tim)]);
     return 0;
    }
    正确代码:
    一:
    #include < cstdio >
    #include < iostream >
    using namespace std;
    int V,n,m,T,A,amount[105][105],f[20000],value[105][105];
    int main()
    {
        scanf("%d%d%d%d",&n,&m,&T,&A);
        if(T>A-1)V=A-1;
        else V=T;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    scanf("%d",&value[i][j]);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    scanf("%d",&amount[i][j]);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    for(int k=1;k<=amount[i][j];k++)
    for(int t=V;t>=2*(i+j);t--)
    if(f[t]
    f[t]=f[t-2*(i+j)]+value[i][j];
        printf("%d",f[V]);
        return 0;
    }
    正确二:
    #include< iostream >
    #include< cstdio >
    #include< vector >
    using namespace std;
    typedef pair< int,int > pi;
    vectorvec;
    int dp[110],a[110][110];
    int main(){
    int m,n;cin>>m>>n;
    int V,temp;
    cin>>V>>temp;
    V=min(V,temp-1);
    for(int i=1;i<=m;i++)
    for(int j=1;j<=n;j++){
    cin>>a[i][j];
    }
    for(int i=1;i<=m;i++){
    for(int j=1;j<=n;j++){
    cin>>temp;
    if(temp!=0){
    int t=1;
    while(temp>t){
    vec.push_back(pi(t*a[i][j],2*t*(i+j)));
    temp-=t;
    t=t<<1;
    }
    if(temp>0)
    vec.push_back(pi(temp*a[i][j],2*temp*(i+j)));
    }
    }
    }
    for(int i=0;i
    int tea=vec[i].first;
    int teb=vec[i].second;
    for(int j=V;j>=teb;j--){
    dp[j]=max(dp[j],dp[j-teb]+tea);
    }
    }
    cout<<dp[V];
    }
  • 相关阅读:
    堆栈学习
    需要阅读的书籍
    Rust Book Lang Ch.19 Fully Qualified Syntax, Supertraits, Newtype Pattern, type aliases, never type, dynamic sized type
    Rust Lang Book Ch.19 Placeholder type, Default generic type parameter, operator overloading
    Rust Lang Book Ch.19 Unsafe
    Rust Lang Book Ch.18 Patterns and Matching
    Rust Lang Book Ch.17 OOP
    Rust Lang Book Ch.16 Concurrency
    Rust Lang Book Ch.15 Smart Pointers
    HDU3966-Aragorn's Story-树链剖分-点权
  • 原文地址:https://www.cnblogs.com/c1299401227/p/5370704.html
Copyright © 2020-2023  润新知