最近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
这题主要有一个把差值当做一维数组的奇技淫巧
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <bits/stdc++.h>
typedef long long LL;
const int N =1e4+100;
using namespace std;
LL dp[51][51][110];
struct node
{
LL l, r, c;
bool operator <(const node &A)const
{
return c<A.c;
}
} p[N];
int main()
{
memset(dp,-1,sizeof(dp));
LL n, m, k1;
scanf("%lld %lld %lld", &n, &m, &k1);
for(int i=0; i<m; i++)
scanf("%lld %lld %lld", &p[i].l,&p[i].r,&p[i].c);
sort(p,p+m);
for(int i=0; i<m; i++)
{
for(int j=0; j<=p[i].r-p[i].l; j++)
{
dp[1][i][j]=j+p[i].l;
}
}
for(int i=2; i<=n; i++)
{
for(int j=0; j<m; j++)
{
for(int k=0; k<=p[j].r-p[j].l; k++)
{
for(int q=0; q<j&&p[q].c<p[j].c; q++)
{
LL tmp=p[j].l+k-k1;
if(tmp>=p[q].l&&tmp<=p[q].r&&dp[i-1][q][tmp-p[q].l]!=-1)
{
dp[i][j][k]=max(dp[i][j][k],dp[i-1][q][tmp-p[q].l]+tmp+k1);
}
tmp+=k1;
if(tmp%k1==0&&(tmp/k1)>=p[q].l&&(tmp/k1)<=p[q].r&&dp[i-1][q][tmp/k1-p[q].l]!=-1)
{
dp[i][j][k]=max(dp[i][j][k],dp[i-1][q][tmp/k1-p[q].l]+tmp);
}
}
}
}
}
LL ans=-1;
for(int i=0; i<m; i++)
{
for(int j=0;j<=p[i].r-p[i].l;j++)
{
ans=max(ans,dp[n][i][j]);
}
}
if(ans==-1)puts("NO");
else
{
puts("YES");
cout<<ans<<endl;
}
return 0;
}