1.摆花
小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共 m 盆。通过调查顾客的喜好,小明列出了顾客最喜欢的 n 种花,从 1 到 n标号。为了在门口展出更多种花,规定第 i种花不能超过 ai 盆,摆花时同一种花放在一起,且不同种类的花需按标号的从小到大的顺序依次摆列。
试编程计算,一共有多少种不同的摆花方案。
输入格式
第一行包含两个正整数 n 和 m ,中间用一个空格隔开。
第二行有 nn 个整数,每两个整数之间用一个空格隔开,依次表示a1 ,a2 ,…, an 。
输出格式
一个整数,表示有多少种方案。注意:因为方案数可能很多,请输出方案数对 1000007 取模的结果。
Inputcopy Outputcopy 2 4 3 2 2
Coding:每种花在每个数量状态下计算
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[1015][105];
int a[105];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
dp[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
{
for(int k=0;k<=min(a[i],j);k++)
dp[i][j]=(dp[i][j]+dp[i-1][j-k])%1000007;
}
cout<<dp[n][m]<<endl;
return 0;
}
2.上学路线
你所在城市的街道好像一个棋盘,有 a 条南北方向的街道和 b 条东西方向的街道。南北方向的 a 条街道从西到东依次编号为 l 到 a,而东西方向的 b 条街道从南到北依次编号为 l 到 b,南北方向的街道 i 和东西方向的街道 j的交点记为 (i,j)。
你住在 (1,1) 处,而学校在 (a,b) 处,你骑自行车去上学,自行车只能沿着街道走,而且为了缩短时间只允许沿着向东和北的方向行驶。
现在有 nn 个交叉路口在施工(X1,Y1)、(X2,Y2)、………、(X_n,Y_n),这些路口是不能通车的。
问你上学一共有多少走法?
输入格式
第一行包含三个整数 a,b,n,分别表示街道的范围,有 n 个路口在维修。
接下来 n 行,每行两个整数 X_i,Y_i,描述路口的位置。
输出格式
输出一个整数表示从 (1,1) 到 (a,b) 的行车路线总数。
样例解释
Sample 1
Inputcopy Outputcopy 5 4 3 2 2 2 3 4 2 5
很老的题了,很经典
Coding:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[20][20];
int main()
{
int a,b,n;
cin>>a>>b>>n;
for(int i=1;i<=b;i++)
for(int j=1;j<=a;j++) dp[i][j]=-1;
int x,y;
for(int i=0;i<n;i++)
{
cin>>x>>y;
dp[y][x]=0;
}
dp[0][1]=1;
for(int i=1;i<=b;i++)
for(int j=1;j<=a;j++)
if(dp[i][j]!=0)
dp[i][j]=dp[i][j-1]+dp[i-1][j];
cout<<dp[b][a];
return 0;
}
3.严酷的训练
蒜头君在韭菜老师的带领下学习 OI,韭菜老师的训练方式很奇怪,他会一口气让蒜头君做很多道题,要求他在规定的时间完成。而韭菜老师为了让自己的威信提高,自己也会把这些题都做一遍。蒜头君和韭菜老师都有一个水平值,他们水平值的比值和做这些题所用时间的比值成反比。比如如果蒜头君的水平值是 1,韭菜老师的水平值是 2,那么蒜头君做同一道题的时间就是韭菜老师的 2 倍。
每个题目有他所属的知识点,这我们都知道,比如递归,动规,最短路,网络流……这里我们不考虑这些事情,我们只知道他们分别是知识点 1,知识点 2……
每一个同一知识点下的题目,对于蒜头君来讲,都是一样难的。做出每一道题,韭菜老师都有其独特的奖励值,而奖励值和题目的知识点没有必然联系。现在蒜头君同学请你帮忙计算,在韭菜老师规定的时间内,他所能得到最大奖励值是多少。
输入格式
第一行两个整数 K_1,K_2,分别表示蒜头君和韭菜老师的水平值。
第二行两个整数 m,n,分别表示题目总数和知识点总数。
第三行 nn 个整数 t_i,表示韭菜老师做每个知识点所花的时间。
接下来 mm 行,每行两个整数 x_i,y_i,表示第 i 题的知识点编号和做出该题的奖励。
最后一行一个整数 T,表示规定的时间。
Inputcopy Outputcopy 1 2 5 4 3 4 5 4 3 2 3 3 4 1 2 2 1 1 26 6
和7.7的题很像,都是在一个固定的条件下
Coding:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=5000+5;
int a[N],dp[N];
int k1,k2,m,n,t;
struct Node
{
int x,y;
}node[N];
int main()
{
cin>>k1>>k2>>m>>n;
for(int i=1;i<=n;i++)
cin>>a[i],a[i]=(k2/k1)*a[i];
for(int i=1;i<=m;i++)
cin>>node[i].x>>node[i].y;
cin>>t;
for(int i=1;i<=m;i++)
for(int j=t;j>=a[node[i].x];j--)
dp[j]=max(dp[j],dp[j-a[node[i].x]]+node[i].y);
cout<<dp[t]<<endl;
return 0;
}