HDU-2159 FATE (DP)

FATE

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11935    Accepted Submission(s): 5656


Problem Description
最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务。久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级。现在的问题是,xhd升掉最后一级还需n的经验值,xhd还留有m的忍耐度,每杀一个怪xhd会得到相应的经验,并减掉相应的忍耐度。当忍耐度降到0或者0以下时,xhd就不会玩这游戏。xhd还说了他最多只杀s只怪。请问他能升掉这最后一级吗?
 
Input
输入数据有多组,对于每组数据第一行输入n,m,k,s(0 < n,m,k,s < 100)四个正整数。分别表示还需的经验值,保留的忍耐度,怪的种数和最多的杀怪数。接下来输入k行数据。每行数据输入两个正整数a,b(0 < a,b < 20);分别表示杀掉一只这种怪xhd会得到的经验值和会减掉的忍耐度。(每种怪都有无数个)
 
Output
输出升完这级还能保留的最大忍耐度,如果无法升完这级输出-1。
 
Sample Input
10 10 1 10
1 1
10 10 1 9
1 1
9 10 2 10
1 1
2 2
 
Sample Output
0
-1
1
 
 
//最近迷上动态规划,难的不会,只好先从水题刷起咯
我先设想的是用一维数组就好了,f[i]保存的是忍耐为 i 的最大经验,转移方程 f[i]=max( f[i] , f[i-b]+a );
然后再用一个数组计数,写完,发现会有个bug,解决不了。。。
只能用二维数组了。
 
先贴下我wa的。。。
 
 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 #define MAX 101
 5 
 6 int dp[MAX];
 7 int num[MAX];
 8 
 9 int main()
10 {
11     int n,m,k,s,a,b;
12     int i,j,flag;
13     while (scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF)
14     {
15         for (i=0;i<=m;i++) 
16         {
17             dp[i]=0;
18             num[i]=0;
19         }
20 
21         for (i=1;i<=k;i++)//怪物数
22         {
23             scanf("%d%d",&a,&b);
24             for (j=b;j<=n;j++)    //忍耐度
25             {
26                 for(p=1;p<=) 
27                 if (dp[j]<=dp[j-b]+a)
28                 {
29                     dp[j]=dp[j-b]+a;
30                     num[j]=num[j-b]+1;       //杀怪 +1 
31                 }
32             }
33         }
34 
35         flag=0;
36         for (i=1;i<=m;i++)
37         {
38             if (dp[i]>=n&&num[i]<=s)
39             {
40                 printf("杀怪数:%d
",num[i]);//输出杀怪数
41                 printf("忍耐值:%d
",m-i);//输出剩余最大忍耐
42                 flag=1;
43                 break;
44             }
45         }
46         if (flag==0) printf("-1
");
47     }
48     return 0;
49 }
View Code

错误原因如下图,在这组输入数据 s=6 的话,第二种输入就是-1,所以不对了

二维数组ac的,f [i] [j] 保存的是 i 忍耐度 j 个杀怪数能获取的最大经验 转移方程是 f [i] [j]=max(f[i][j],f[i-b][j-1]+a);

15ms

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 #define MAX 101
 5 
 6 int dp[MAX][MAX];
 7 
 8 int main()
 9 {
10     int n,m,k,s,a,b;
11     int i,j,p;
12     while (scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF)
13     {
14         memset(dp,0,sizeof(dp));
15 
16         for (i=1;i<=k;i++)        //怪物数
17         {
18             scanf("%d%d",&a,&b);
19 
20             for (j=b;j<=m;j++)    //忍耐度
21             {
22                 for(p=1;p<=s;p++) //杀怪数
23                 {
24                     if(dp[j][p]<dp[j-b][p-1]+a)
25                         dp[j][p]=dp[j-b][p-1]+a;
26                 }
27             }
28 
29         }
30 
31         if (dp[m][s]>=n)//可以升级
32         {
33             for (i=1;i<=m;i++)
34                 if (dp[i][s]>=n)
35                 {
36                     printf("%d
",m-i);
37                     break;
38                 }
39         }
40         else
41             printf("-1
");
42     }
43     return 0;
44 }
View Code
 
原文地址:https://www.cnblogs.com/haoabcd2010/p/5737433.html