• RQNOJ 117 最佳课题选择:多重背包


    题目链接:https://www.rqnoj.cn/problem/117

    题意:

      NaCN_JDavidQ要在下个月交给老师n篇论文,论文的内容可以从m个课题中选择。

      由于课题数有限,NaCN_JDavidQ不得不重复选择一些课题。

      对于某个课题i,若NaCN_JDavidQ计划一共写x篇论文,则完成该课题的论文总共需要花费Ai*(x^Bi)个单位时间(系数Ai和指数Bi均为正整数)。

      给定与每一个课题相对应的Ai和Bi的值,请帮助NaCN_JDavidQ计算出如何选择论文的课题使得他可以花费最少的时间完成这n篇论文。

    题解:

      转化问题:

        (将对象由论文转化为课题)

        有m个课题。

        对于每个课题,你可以写任意篇论文。

        问你恰好写完n篇论文的最小时间。

     

      表示状态:

        dp[i][j] = min time

        i:考虑到第i个课题

        j:已经完成了j篇论文

      找出答案:

        ans = dp[m][n]

      如何转移:

        now: dp[i][j]

        dp[i+1][j+k] = min dp[i][j] + a[i]*(k^b[i])

        第i个课题写了k篇论文

      边界条件:

        dp[0][0] = 0

        others = -1

      注:本题会爆int。。。

    AC Code:

     1 // state expression:
     2 // dp[i][j] = min time
     3 // i: considering ith project
     4 // j: finished j papers
     5 //
     6 // find the answer:
     7 // dp[m][n]
     8 //
     9 // transferring:
    10 // now: dp[i][j]
    11 // dp[i+1][j+k] = min dp[i][j] + a[i]*k^b[i]
    12 //
    13 // boundary:
    14 // dp[0][0] = 0
    15 // others = -1
    16 #include <iostream>
    17 #include <stdio.h>
    18 #include <string.h>
    19 #define MAX_N 205
    20 #define MAX_M 25
    21 
    22 using namespace std;
    23 
    24 int n,m;
    25 int a[MAX_M];
    26 int b[MAX_M];
    27 long long dp[MAX_M][MAX_N];
    28 
    29 void read()
    30 {
    31     cin>>n>>m;
    32     for(int i=0;i<m;i++)
    33     {
    34         cin>>a[i]>>b[i];
    35     }
    36 }
    37 
    38 long long quick_pow(long long n,long long k)
    39 {
    40     long long ans=1;
    41     while(k)
    42     {
    43         if(k&1)
    44         {
    45             ans*=n;
    46         }
    47         n*=n;
    48         k>>=1;
    49     }
    50     return ans;
    51 }
    52 
    53 void solve()
    54 {
    55     memset(dp,-1,sizeof(dp));
    56     dp[0][0]=0;
    57     for(int i=0;i<m;i++)
    58     {
    59         for(int j=0;j<=n;j++)
    60         {
    61             if(dp[i][j]!=-1)
    62             {
    63                 for(int k=0;j+k<=n;k++)
    64                 {
    65                     long long now=dp[i][j]+a[i]*quick_pow(k,b[i]);
    66                     if(dp[i+1][j+k]==-1 || dp[i+1][j+k]>now)
    67                     {
    68                         dp[i+1][j+k]=now;
    69                     }
    70                 }
    71             }
    72         }
    73     }
    74 }
    75 
    76 void print()
    77 {
    78     cout<<dp[m][n]<<endl;
    79 }
    80 
    81 int main()
    82 {
    83     read();
    84     solve();
    85     print();
    86 }
  • 相关阅读:
    MySQL5.7二进制安装及多实例
    MySQL5.7版本的yum安装方式
    PHP安装
    MySQL5.6安装部署及多实例主从
    Prometheus监控MySQL和Linux主机结合Grafana出图
    MySQL5.7源码安装(编译)
    MySQL基本管理
    WC框架
    .NET 调用虚方法2 转
    .NET 调用虚方法1 转
  • 原文地址:https://www.cnblogs.com/Leohh/p/7461287.html
Copyright © 2020-2023  润新知