RQNOJ 140 分配时间:dp

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

题意:

  小王参加的考试是几门科目的试卷放在一起考,一共给t分钟来做。

  他现在已经知道第i门科目花k分钟可以拿到w[i][k]分。

  写名字需要的时间为name(他写自己的名字很慢)

  如果放弃某一门的考试(花的时间为0),那么名字也就不用写了。

  问他最高能得几分。

 

题解:

  表示状态:

    dp[i][j] = max score

    i:考虑到第i们科目

    j:当前花费的时间

 

  找出答案:

    max dp[n][j]

 

  如何转移:

    now: dp[i][j]

    dp[i+1][j+k] = max dp[i][j] + w[i][k] + (k==0 ? 0 : name)

    枚举k为当前科目用的时间。k为0时相当于放弃本科目,也就不用写名字。

 

  边界条件:

    dp[0][0] = 0

    others = -1

 

AC Code:

 1 // state expression:
 2 // dp[i][j] = max score
 3 // i: considering ith subject
 4 // j: cost time
 5 //
 6 // find the answer:
 7 // max dp[n][j]
 8 //
 9 // transferring:
10 // now: dp[i][j]
11 // dp[i+1][j+k] = max dp[i][j] + w[i][k] + (k==0 ? 0 : name)
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 15
20 #define MAX_T 105
21 
22 using namespace std;
23 
24 int n,t;
25 int name;
26 int ans;
27 int w[MAX_N][MAX_T];
28 int dp[MAX_N][MAX_T];
29 
30 void read()
31 {
32     cin>>t>>n>>name;
33     for(int i=0;i<n;i++)
34     {
35         w[i][0]=0;
36         for(int j=1;j<=t;j++)
37         {
38             cin>>w[i][j];
39         }
40     }
41 }
42 
43 void solve()
44 {
45     memset(dp,-1,sizeof(dp));
46     dp[0][0]=0;
47     for(int i=0;i<n;i++)
48     {
49         for(int j=0;j<=t;j++)
50         {
51             if(dp[i][j]!=-1)
52             {
53                 for(int k=0;k<=t;k++)
54                 {
55                     int tim=j+k+(k==0?0:name);
56                     if(tim<=t) dp[i+1][tim]=max(dp[i+1][tim],dp[i][j]+w[i][k]);
57                     else break;
58                 }
59             }
60         }
61     }
62     ans=0;
63     for(int i=0;i<=t;i++)
64     {
65         ans=max(ans,dp[n][i]);
66     }
67 }
68 
69 void print()
70 {
71     cout<<ans<<endl;
72 }
73 
74 int main()
75 {
76     read();
77     solve();
78     print();
79 }

 

posted @ 2017-09-01 01:25  Leohh  阅读(215)  评论(0编辑  收藏  举报