您的位置:首页 > 其它

Codeforces Beta Round #90 C. Education Reform

2014-08-25 02:48 441 查看
先把课程按照难度排序。

dp[i][j][k]表示已经选了i门课,最后选出的一门课是排序后的第j个,最后一门课安排的作业量是k+p[j].a的时候最多的作业量和是多少。转移的时候枚举下一门选择的课程,判断下K*(p[j].a+k),K+(p[j].a+k)和下一门课程作业的范围之间的关系就可以了,dp时维护路径,输出解。注意不要用非法状态去转移。

#include <bits/stdc++.h>
using namespace std;
__int64 dp[51][51][109];
int X[51][51][109],Y[51][51][109];
struct node
{
__int64 a,b;
int c,id;
bool operator<(const node &rhs)const
{
return c<rhs.c;
}
}p[55];
int n,m,K;
void output(int dep,int x,int y)
{
if(dep==0)
return ;
output(dep-1,X[dep][x][y],Y[dep][x][y]);
printf("%d %I64d\n",p[x].id,p[x].a+y);
}
int main()
{
scanf("%d%d%d",&n,&m,&K);
for(int i=1;i<=m;i++)
{
scanf("%I64d%I64d%d",&p[i].a,&p[i].b,&p[i].c);
p[i].id=i;
}
sort(p+1,p+1+m);
for(int i=1;i<=m;i++)
{
for(int j=0;j<=p[i].b-p[i].a;j++)
{
dp[1][i][j]=p[i].a+j;
}
}
for(int i=1;i<n;i++)
{
for(int j=i;j<=m;j++)
{
for(int k=0;k<=p[j].b-p[j].a;k++)
{
__int64 cur=p[j].a+k;
if(dp[i][j][k]==0)
continue;               //非法状态
for(int x=j+1;x<=m;x++)
{
if(p[x].c==p[j].c)
continue;
if(p[x].a<=cur+K&&cur+K<=p[x].b)
{
if(dp[i+1][x][cur+K-p[x].a]<dp[i][j][k]+K+cur)
{
dp[i+1][x][cur+K-p[x].a]=dp[i][j][k]+K+cur;
X[i+1][x][cur+K-p[x].a]=j;
Y[i+1][x][cur+K-p[x].a]=k;
}
}
if(p[x].a<=cur*K&&cur*K<=p[x].b)
{
if(dp[i+1][x][cur*K-p[x].a]<dp[i][j][k]+K*cur)
{
dp[i+1][x][cur*K-p[x].a]=dp[i][j][k]+K*cur;
X[i+1][x][cur*K-p[x].a]=j;
Y[i+1][x][cur*K-p[x].a]=k;
}
}
}
}
}
}
__int64 ans=0;
int x,y;
for(int i=1;i<=m;i++)
for(int j=0;j<=100;j++)
{
if(ans<dp
[i][j])
{
ans=dp
[i][j];
x=i;y=j;
}
}
if(ans==0)
{
printf("NO\n");
}
else
{
printf("YES\n");
output(n,x,y);
}
//system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: