http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1636
题目来源: CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
收藏
关注
最近A学校正在实施教育改革。
一个学年由n天组成。A学校有m门课程,每天学生必须学习一门课,一门课程必须在一天内学习完。在学习完第i门课程后,学生们会收到 xi 个家庭作业,其中 xi是区间[ai,bi]里的一个整数 。每门课还有一个属性,就是复杂度 ci 。A学校现在要制他们的课程表,具体要求如下:
·在课程表中,随着天数的增加,课程的复杂度是严格递增的。
·除了第1天,每天的作业量必须是前一天的k倍,或者比前一天多k个作业。(假设第i天的作业量为 xi ,则对于i(1<i≤n)到满足 xi = k+xi−1 或 xi = k⋅xi−1 );
现在,给定天数n,系数k,和m门课程的ai,bi,ci(1≤i≤m)。要求计算一个学年可以安排最大的总作业量( 总作业量的表达式是∑ni=1xi )是多少。
Input
单组测试数据 第一行,三个由空格隔开的整数n,m,k(1≤n≤m≤50,1≤k≤100),表示一个学年的天数,课程的数量,和作业增量系数。 接下来的m行, 每行有三个整数,ai,bi,ci(1≤ai≤bi≤10^16,bi-ai≤100,1≤ci≤100) 分别表示第i门课程的最小作业量,和最多作业量,以及复杂度。 不同的课程可以有相同的复杂度。课程编号从1到m。
Output
如果有可行方案,第一行输出“YES”(没有引号),第二行输出最大的作业量。 如果没有可行方案,则输出一行“NO”(没有引号)。
Input示例
4 5 2 1 10 1 1 10 2 1 10 3 1 20 4 1 100 5
Output示例
YES 78
数据不大,就是条件太多了容易忽略一些条件= =,要注意课程的复杂度必须是严格递增的,相等是不允许的,每门课程获得的作业量不能超出所给的范围。
f[i][j][k]表示第i天选择了第j门课程,当天获得P[j].a+k个作业可获得的总作业数的最大值。从前一天枚举合法的课程递推就好了,注意要保证前一天存在方案才可递推(f[i][j][k]>0)。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 LL f[51][51][101]; 6 struct node 7 { 8 LL a,b,c; 9 bool operator<(const node& chs)const{ 10 return c<chs.c; 11 } 12 }P[55]; 13 int main() 14 { 15 long long n,m,temp,k,i,j; 16 cin>>n>>m>>temp; 17 for(i=1;i<=m;++i){ 18 scanf("%lld%lld%lld",&P[i].a,&P[i].b,&P[i].c); 19 } 20 sort(P+1,P+1+m); 21 memset(f,0,sizeof(f)); 22 for(j=1;j<=m;++j) 23 { 24 for(k=0;k<=P[j].b-P[j].a;++k) 25 { 26 f[1][j][k]=P[j].a+k; 27 } 28 } 29 for(i=2;i<=n;++i) 30 { 31 for(j=1;j<=m;++j) 32 { 33 for(int _j=1;_j<j;++_j) 34 { 35 if(P[_j].c<P[j].c){ 36 for(k=0;k<=P[j].b-P[j].a;++k) 37 { 38 long long _k=P[j].a+k-temp-P[_j].a; 39 if(_k>=0&&_k<=P[_j].b-P[_j].a&&f[i-1][_j][_k]){ 40 f[i][j][k]=max(f[i][j][k],f[i-1][_j][_k]+P[j].a+k); 41 } 42 if((P[j].a+k)%temp==0){ 43 long long _k=(P[j].a+k)/temp-P[_j].a; 44 if(_k>=0&&_k<=P[_j].b-P[_j].a&&f[i-1][_j][_k]){ 45 f[i][j][k]=max(f[i][j][k],f[i-1][_j][_k]+P[j].a+k); 46 } 47 } 48 } 49 } 50 } 51 } 52 } 53 LL ans=0; 54 for(j=1;j<=m;++j) 55 for(k=0;k<=P[j].b-P[j].a;++k) 56 ans=max(ans,f[n][j][k]); 57 if(ans==0)puts("NO"); 58 else{ 59 puts("YES"); 60 cout<<ans<<endl; 61 } 62 return 0; 63 }