• 2021.5.29 开心赛(背包经典题) (下)


    6、最小乘车费用(这题我在洛谷没找到)

    • 题目描述
      
      假设某条街上每 一公里 就有一个公共汽车站,并且乘车费用如下表: 
      
      公里数 1 2 3 4 5 6 7 8 9 10
      费用 12 21 31 40 49 58 69 79 90 101 
      
      而任意一辆汽车从不行驶超过 10 公里 。某人想行驶 n(1<=n<=100) 公里,假设他可以任意次换车,请你帮他找到一种乘车方案,使得总费用最小 
      
      
      注意: 10 公里 的费用比 1 公里 小的情况是允许的。 
      
      
      输入
      
      共两行,第一行为 10 个不超过 200 的整数,依次表示行驶 110 公里的费用,相邻两数间用一个空格隔开;第二行为某人想要行驶的公里数。
      
       
      
      输出
      
      仅一行,包含一个整数,表示行使这么远所需要的最小费用。 
      
      
      样例输入
      
      12 21 31 40 49 58 69 79 90 101
      15
      
      样例输出
      
      147
    • 心路历程(跟殳哥学的):这题是个完全背包。蒟蒻如我在判断出来类型之后就卡住了,样例都过不了,后来发现自己没赋初值就用min了……我已经习惯了自己犯各种各样奇葩错误了……
    • 代码实现:
       1 #include <bits/stdc++.h>
       2 using namespace std;
       3 long long w[15];
       4 long long m;
       5 long long dp[2005]={};
       6 int main()
       7 {
       8     for(int i=1;i<=10;i++)
       9     {
      10         scanf("%lld",&w[i]);
      11     }
      12     scanf("%lld",&m);
      13     
      14     dp[0]=0;
      15     for(int i=1;i<=m;i++)
      16     {
      17         dp[i]=1<<30;
      18         for(int j=1;j<=10;j++)
      19         {
      20             if(i>=j)
      21             {
      22                 dp[i]=min(dp[i-j]+w[j],dp[i]);//i和j!!!! 
      23             }
      24         }
      25     }
      26     printf("%lld",dp[m]);
      27     return 0;
      28                 

    7、质数和分解

    • 心路历程:这题最开始卡了我好久,后来发现自己素数筛写错了……然后就没什么了。
    • 代码实现:
       1 #include <bits/stdc++.h>
       2 using namespace std;
       3 int n;
       4 int isprime[1005];
       5 int dp[2005];
       6 
       7 bool prime(int x)
       8 {
       9     for(int i=2;i<=sqrt(x);i++)
      10     {
      11             if(x%i==0)
      12             {
      13                 return 0;
      14             }
      15         
      16         }
      17     return 1;//函数结果写外面!!!! 
      18 }
      19 int main()
      20 {
      21     while(cin>>n)
      22     {
      23         int w=0;
      24         for(int i=2;i<=n;i++)
      25         {
      26             if(prime(i))
      27             {
      28                 w++;
      29                 isprime[w]=i;
      30             }
      31         }
      32         memset(dp,0,sizeof(dp));
      33         dp[0]=1;
      34 
      35         for(int i=1;i<=w;i++)
      36         {
      37             for(int j=isprime[i];j<=200;j++)
      38             {
      39                 dp[j]+=dp[j-isprime[i]];
      40             }
      41         }
      42         cout<<dp[n]<<endl; 
      43     }
      44     return 0;
      45 }

    8、逃亡的准备

    【问题描述】
      在《Harry Potter and the Deathly Hallows》中,Harry Potter他们一起逃亡,现在有许多的东西要放到赫敏的包里面,但是包的大小有限,所以我们只能够在里面放入非常重要的物品。现在给出该种物品的数量、体积、价值的数值,希望你能够算出怎样能使背包的价值最大的组合方式,并且输出这个数值,赫敏会非常感谢你。
    【输入格式】
      第1行有2个整孰物品种数n和背包装载体积v;
      第2行到i+l行每行3个整数,为第i种物品的数量m、体积w、价值s。
    【输出格式】
      仅包含一个整数,即为能拿到的最大的物品价值总和。
    【输入样例】
      2 10
      3 4 3
      2 2 5
    【输出样例】
      13
      样例说明:选第一种一个,第二种两个,结果为3×1+5×2=13。
    【数据规模】
      对于30%的数据:1≤v≤500;1≤n≤2000;l≤m≤10;1≤w≤20;1≤s≤100;
      对于lOffl6的数据:1≤v≤500;1≤n≤2000;1≤m≤5000;1≤w≤20;1≤s≤100
    • 心路历程:一眼就是板子题。卡了三十分之后,听机房大佬说,这题卡常数,要加特判。我又看了其他人的博客,发现很多人用二进制拆分。

    • 代码实现:
      #include <bits/stdc++.h>
      using namespace std;
      int n,v;
      int s[2005],w[2005],m[2005];
      int dp[10005]={};
      
      int main()
      {
          scanf("%d %d",&n,&v);
          for(int i=1;i<=n;i++)
          {
              scanf("%d %d %d",&m[i],&w[i],&s[i]);    
          }
          
          for(int i=1;i<=n;i++)
          {
              for(int j=v;j>w[i];j--)
              {
                  for(int k=1;k<=m[i];k++)
                  {
                      if(k*w[i]<=j)
                      {
                          dp[j]=max(dp[j],dp[j-k*w[i]]+k*s[i]);
                      }
                      else
                      {
                          break;//如果只取一个都不行,那后面就没有再看的意义了
                      }
                  
                  }
              }
          }
          printf("%d",dp[v]);
          return 0;
      }
      /*
      2 10
      3 4 3
      2 2 5
      */

    4、暗黑游戏

    • 这题我被卡了四十分!
    • #include <bits/stdc++.h>
      using namespace std;
      int pg, ru, n;
      int p[500], r[500], k[500], c[500];
      int dp[2005][2005] = {};
      
      int main() {
          scanf("%d %d %d", &n, &pg, &ru);
          for (int i = 1; i <= n; i++) {
              scanf("%d %d %d %d", &p[i], &r[i], &k[i], &c[i]);
          }
      
          for (int i = 1; i <= n; i++) {
              if (k[i] == 0) {
                  for (int j = pg; j >= p[i]; j--) {
                      for (int h = ru; h >= r[i]; h--) {
                          dp[j][h] = max(dp[j][h], dp[j - p[i]][h - r[i]] + c[i]);
                      }
                  }
              } else {
                  for (int j = pg; j >= p[i]; j--) {
                      for (int h = ru; h >= r[i]; h--) {
                          for (int w = 0; w <= k[i]; w++) {
                              if (w * p[i] <= j && w * r[i] <= h) {
                                  dp[j][h] = max(dp[j][h], dp[j - w * p[i]][h - w * r[i]] + w * c[i]);
                              }
                          }
                      }
                  }
              }
          }
      
          printf("%d", dp[pg][ru]);
          return 0;
      }
      /*
      3 10 10
      5 3 0 110
      4 3 4 120
      2 3 1 130
      */
  • 相关阅读:
    Oracle 查看一个表对应的主键和外键的约束关系,查看的语句:
    openssl 生成p12文件错误
    XP SP3远程桌面无法连接Windows Server 2008/Vista
    windows 7 正确禁用 IPv6
    用正则表达式替换换行符
    Eclipse插件开发之定制向导(各方法说明)
    oepnvpn 配置自启动
    TNS12547: TNS:lost contact 错误解决
    redhat 5.5 U盘安装
    Hibernat 使用Criteria查询多对多关系(SET集合)条件
  • 原文地址:https://www.cnblogs.com/TheZealous/p/14825922.html
Copyright © 2020-2023  润新知