https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1636
中文题意,不在赘述。
首先写的一个回溯,被一组数据卡了。(应该是这一组非法状态太多)
考虑到每门科目的作业区间很小。用动态规划搞之。
dp[i][j][k] 为1-i天,末尾为j课程,选择的作业数目为k(考虑到太大,用和左边界的差值表示)
原题中还有x和y记录课程号和作业数,用来递归输出。
wa了几点。如果非法状态用0表示,那么最后的ans也应该是0。不然就不会输出no。
用long long
附 回溯代码(也调了好久qwq)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100;
ll dp[maxn][maxn][maxn];
int m,n;ll k;
struct Node{
ll l,r,lim;
}node[maxn];
bool cmp2(Node a,Node b){
return a.lim<b.lim;
}
int main()
{ while(~scanf("%d%d%lld",&m,&n,&k)){
for(int i=0;i<n;i++){
scanf("%lld%lld%lld",&node[i].l,&node[i].r,&node[i].lim);
}
memset(dp,-1,sizeof(dp));
sort(node,node+n,cmp2);
for(int i=0;i<n;i++){
for(ll j=node[i].l;j<=node[i].r;j++)
dp[1][i][j-node[i].l]=1ll*j;
}
for(int i=1;i<=m;i++){
for(int j=i-1;j<n;j++){
for(ll x=node[j].l;x<=node[j].r;x++){
if(dp[i][j][x-node[j].l]==-1)
continue;
for(int jj=j+1;jj<n;jj++){
if(node[jj].lim<=node[j].lim) continue;
if(x*k>=node[jj].l&&x*k<=node[jj].r){
if(dp[i+1][jj][x*k-node[jj].l]<(x*k+dp[i][j][x-node[j].l])){
dp[i+1][jj][x*k-node[jj].l]=x*k+dp[i][j][x-node[j].l];
}
}
if(1ll*(x+k)>=node[jj].l&&1ll*(x+k)<=node[jj].r){
if(dp[i+1][jj][x+k-node[jj].l]<(x+k+dp[i][j][x-node[j].l])){
dp[i+1][jj][x+k-node[jj].l]=1ll*(x+k+dp[i][j][x-node[j].l]);
}
}
}
}
}
}
ll ans=-1;
for(int i=0;i<n;i++){
for(ll j=node[i].l;j<=node[i].r;j++){
ans=max(ans,dp[m][i][j-node[i].l]);
}
}
if(ans!=-1){
puts("YES");
printf("%lld\n",ans);
}
else
puts("NO");
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
/*回溯,就t一组。
*/
const int maxn=1e5;
typedef long long ll;
const ll inf=1e17;
struct Node{
ll l,r;
ll dif;
}node[maxn];
bool cmp2(Node a,Node b){
return a.dif<b.dif;
}
ll lim;
int m,n;
ll ans;
bool vis[maxn];
int siz;
void dfs(int x,ll s,ll chi){
if(siz==m){
ans=max(ans,s);
return ;
}
for(int i=x;i<n;i++){
if(!vis[i]&&node[i].dif>node[x].dif){
if(max(chi*lim,chi+lim)>=node[i].l&&max(chi*lim,chi+lim)<=node[i].r){
//s+=max(chi*lim,chi+lim);
//cout<<x<<"fir"<<i<<" "<<siz<<endl;
vis[i]=true;
siz++;
dfs(i,s+max(chi*lim,chi+lim),max(chi*lim,chi+lim));
vis[i]=false;
siz--;
}
if(min(chi*lim,chi+lim)>=node[i].l&&min(chi*lim,chi+lim)<=node[i].r){
siz++;
vis[i]=true;
dfs(i,s+min(chi*lim,chi+lim),min(chi*lim,chi+lim));
vis[i]=false;
siz--;
}
//vis[i]=false;
//dfs(i+1,s,chi);
}
}
}
int main()
{ int t;
while(~scanf("%d%d%lld",&m,&n,&lim)){
for(int i=0;i<n;i++){
scanf("%lld%lld%lld",&node[i].l,&node[i].r,&node[i].dif);
}
sort(node,node+n,cmp2);
ans=-1;
//cout<<"??"<<endl;
/*for(int i=0;i<n;i++)
for(ll j=node[i].l;j<=node[i].r;j++){
memset(vis,false,sizeof(vis)); siz=0;
siz=1;
vis[i]=true;
//cout<<i<<" "<<j<<endl;*/
for(int i=0;i<n;i++)
for(ll j=node[i].l;j<=node[i].r;j++){
memset(vis,false,sizeof(vis));
siz=1;
dfs(i,j,j);
}
// }
if(ans!=-1){
puts("YES");
printf("%lld\n",ans);
}
else
puts("NO");
}
return 0;
}