18.03.10 vijos1025小飞侠的游园方案

描述

经过抽签选择,小智将军第一个进入考场。

菜虫:(身上散射出华贵(?)的光芒)欢迎你,第一位挑战者!!
小智:……(走到菜虫身后,关灯)女王陛下,虽然我们国家现在很富裕,但也请您不要浪费电来用这么大功率的灯泡。

菜虫(汗):啊啊~~爱卿所言甚是~~那么,你的题目是……我们的情报组织探听到敌人的重要将领——小飞侠星期天会邀他的灵儿妹妹到公园去玩。公园里有很多娱乐项目,可并不是每一项他们都喜欢,所以他们对每一项都进行了“喜欢度”的评分。因为小飞侠也是一个了不起的角色,所以他一定会选择在有限时间内的最好的方案。现在要你做的就是找出在规定时间内他们选择哪几项不同的活动可以使其“喜欢度”之和达到最大,据此我们就可以知道他会在哪些地方出现,从而在那里派人看守了。

小智:(灯泡一亮)每个地方都派人看守不就行了?!
“当~~~” 
菜虫:(手执八公分直径炒锅,筋)……你是白痴吗?-_-##(都派人去看守的话我们会有多少桌三缺一?!)听好了,输入格式是第一行一个正整数N(1<=N<=100)表示总共的娱乐项目数;第二行一个正整数表示规定的时间t(0<t<1000);下面有N行,其中第i+2行有两个正整数fi(0<=fi<=100)和ti(0<ti<=100),分别表示对项目i的“喜欢度”和它所耗费的时间。输出的时候在第一行输出最大的“喜欢度”之和,下面给你一个样例:

样例1

样例输入1

3
5
1 2
5 5
4 3

样例输出1

5

限制

各个测试点1s

来源

Vivian Snow
From 正·蠢盟演义——战略版 Fools-League Tactics

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <stdlib.h>
 4 #include <algorithm>
 5 #include <math.h>
 6 
 7 using namespace std;
 8 
 9 int pro[103][3],f[102][1002]={0};//pro[][1]是喜欢度 pro[][2]是时间花费 f[x][y]表示y时间内选x种项目的最高喜好度
10 
11 int main()
12 {
13     int n,t;//n项目数 t总时间
14     scanf("%d%d",&n,&t);
15     for(int i=1;i<=n;i++)
16     {
17         scanf("%d%d",&pro[i][1],&pro[i][2]);
18     }
19     for(int i=1;i<=t;i++)
20         for(int j=1;j<=n;j++)
21         {
22             if(j==1&&pro[j][2]<=i)
23                 f[j][i]=pro[j][1];
24             else if(j!=1)
25             {
26                 if(pro[j][2]>i)
27                     f[j][i]=f[j-1][i];
28                 else
29                         f[j][i]=max(f[j-1][i],f[j-1][i-pro[j][2]]+pro[j][1]);
30             }
31         }
32     printf("%d",f[n][t]);
33     return 0;
34 }
View Code

01背包 很套路的解法

但我看到了别人的 看上去超短的解法 于是改了一下又ac了一次

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <stdlib.h>
 4 #include <algorithm>
 5 #include <math.h>
 6 
 7 using namespace std;
 8 
 9 int f[1002];//f[y]表示y时间内选n种项目的最高喜好度
10 
11 int main()
12 {
13     int n,t;//n项目数 t总时间
14     scanf("%d%d",&n,&t);
15     for(int i=1;i<=n;i++)
16     {
17         int a,b;
18         scanf("%d%d",&a,&b);
19         for(int j=t;j>=b;j--)
20             f[j]=max(f[j],f[j-b]+a);
21     }
22     printf("%d",f[t]);
23     return 0;
24 }
View Code

其实思路是一模一样的 就是通过一条特别的路径将同一个时间内不管选取多少种项目的情况都合并到同一个数组了 然后把项目一个一个加进去 更新数值

注定失败的战争,也要拼尽全力去打赢它; 就算输,也要输得足够漂亮。
原文地址:https://www.cnblogs.com/yalphait/p/8540397.html