51nod 1636

时间:2023-03-08 19:18:44
51nod 1636

1636 教育改革

我看过题解了还下了数据,表示很惭愧不想说什么,但还是说两句吧

sol:

因为差值很小只有100,所以对数组下标存的是(选择的数值和左端点的差值)

f[i][j][k]即为第i天选了第j课 k为上述内容 还有注意转移的时候要保证上一个合法才能转到下一个,就是上一个一定不为0;

听起来不难然而我还是看了题解qwq

#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node{int l, r, c;}a[];
inline bool cmp(node a,node b){return a.c < b.c;}
int n, m, K, f[][][], ans;
signed main()
{
freopen("51nod1636.in","r",stdin);
while(~scanf("%lld%lld%lld", &n, &m, &K))
{
ans = ;
memset(f, , sizeof f);
for(int i = ; i <= m; i++)
scanf("%lld%lld%lld", &a[i].l, &a[i].r, &a[i].c);
sort(a + , a + m + , cmp);
for(int i = ; i <= m; i++)
for(int j = ; j <= a[i].r - a[i].l; j++)
f[][i][j] = a[i].l + j;
for(int i = ; i <= n; i++)
for(int j = ; j <= m; j++)
for(int jj = ; jj < j; jj++)
{
if(a[j].c > a[jj].c)
for(int k = , oo; k <= a[j].r - a[j].l; k++)
{
oo = a[j].l + k - K;
if (oo >= a[jj].l && oo <= a[jj].r && f[i - ][jj][oo - a[jj].l])
f[i][j][k] = max(f[i][j][k], f[i - ][jj][oo - a[jj].l] + a[j].l + k);
if ((a[j].l + k) % K == )
{
oo = (a[j].l + k) / K;
if (oo >= a[jj].l && oo <= a[jj].r && f[i - ][jj][oo - a[jj].l])
f[i][j][k] = max(f[i][j][k], f[i - ][jj][oo - a[jj].l] + a[j].l + k);
}
}
}
for(int i = ; i <= m; i++)
for(int j = ; j <= a[i].r - a[i].l; j++)
ans = max(ans, f[n][i][j]);
if (ans) printf("YES\n%lld\n", ans);
else printf("NO\n");
}
}