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 }
原文地址:https://www.cnblogs.com/Leohh/p/7461287.html