我看过题解了还下了数据,表示很惭愧不想说什么,但还是说两句吧
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[55]; inline bool cmp(node a,node b){return a.c < b.c;} int n, m, K, f[55][55][105], ans; signed main() { freopen("51nod1636.in","r",stdin); while(~scanf("%lld%lld%lld", &n, &m, &K)) { ans = 0; memset(f, 0, sizeof f); for(int i = 1; i <= m; i++) scanf("%lld%lld%lld", &a[i].l, &a[i].r, &a[i].c); sort(a + 1, a + m + 1, cmp); for(int i = 1; i <= m; i++) for(int j = 0; j <= a[i].r - a[i].l; j++) f[1][i][j] = a[i].l + j; for(int i = 2; i <= n; i++) for(int j = 2; j <= m; j++) for(int jj = 1; jj < j; jj++) { if(a[j].c > a[jj].c) for(int k = 0, 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 - 1][jj][oo - a[jj].l]) f[i][j][k] = max(f[i][j][k], f[i - 1][jj][oo - a[jj].l] + a[j].l + k); if ((a[j].l + k) % K == 0) { oo = (a[j].l + k) / K; if (oo >= a[jj].l && oo <= a[jj].r && f[i - 1][jj][oo - a[jj].l]) f[i][j][k] = max(f[i][j][k], f[i - 1][jj][oo - a[jj].l] + a[j].l + k); } } } for(int i = 1; i <= m; i++) for(int j = 0; j <= a[i].r - a[i].l; j++) ans = max(ans, f[n][i][j]); if (ans) printf("YES %lld ", ans); else printf("NO "); } }