首页 > 代码库 > 最佳课题选择
最佳课题选择
最佳课题选择
时间限制: 1 Sec 内存限制: 128 MB题目描述
Matrix67要在下个月交给老师n篇论文,论文的内容可以从m个课题中选择。由于课题数有限,Matrix67不得不重复选择一些课题。完成不同课题的论文所花的时间不同。具体地说,对于某个课题i,若Matrix67计划一共写x篇论文,则完成该课题的论文总共需要花费Ai*x^Bi个单位时间(系数Ai和指数Bi均为正整数)。给定与每一个课题相对应的Ai和Bi的值,请帮助Matrix67计算出如何选择论文的课题使得他可以花费最少的时间完成这n篇论文。
输入
第一行有两个用空格隔开的正整数n和m,分别代表需要完成的论文数和可供选择的课题数。
以下m行每行有两个用空格隔开的正整数。其中,第i行的两个数分别代表与第i个课题相对应的时间系数Ai和指数Bi。
对于30%的数据,n< =10,m< =5;
对于100%的数据,n< =200,m< =20,Ai< =100,Bi< =5。
输出
输出完成n篇论文所需要耗费的最少时间。
样例输入
10 3
2 1
1 2
2 1
样例输出
19
提示
样例说明:
4篇论文选择课题一,5篇论文选择课题三,剩下一篇论文选择课题二,总耗时为2*4^1+1*1^2+2*5^1=8+1+10=19。可以证明,不存在更优的方案使耗时小于19。
题解:
一道很水的DP,f[i][j]表示选前i种论文完成j篇的最少时间。
g[i][j]为预处理出的在第i种论文上写j篇所需要的时间。
f[i][j]=min(f[i][j],f[i-1][k]+g[i][j-k]);
事实上如果追求效率的话可以降成一维的,当然还可以用快速幂优化。
二维代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<queue> #include<stack> #include<ctime> #include<vector> using namespace std; int n,m; long long f[21][201],g[21][201],a[21],b[21]; int main() { int i,j,k; scanf("%d%d",&n,&m); for(i=1;i<=m;i++) scanf("%lld%lld",&a[i],&b[i]); for(i=1;i<=m;i++) { for(j=1;j<=n;j++) { long long s=1; for(k=1;k<=b[i];k++)s*=j; f[i][j]=g[i][j]=s*a[i]; } } for(i=2;i<=m;i++) { for(j=1;j<=n;j++) { for(k=0;k<=j;k++) { f[i][j]=min(f[i][j],f[i-1][k]+g[i][j-k]); } } } cout<<f[m][n]; return 0; }
最佳课题选择
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。