题解:P2157 [SDOI2009] 学校食堂
题目传送门
题目大意
有
解题思路
首先,我们发现
现在我们考虑转移,首先如果枚举到的
这个转移式比较好理解,
如果
转移式借助代码会好理解很多,其中的
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1010;
ll t[N],b[N],dp[N][258][20],ans;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
ll T;
cin>>T;
while(T--){
ll n,m;
cin>>n;
for(int i=1;i<=n;i++)cin>>t[i]>>b[i];
memset(dp,0x3f,sizeof(dp));
dp[1][0][7]=0;
for(int i=1;i<=n;i++){
for(int j=0;j<(1<<8);j++){
for(int k=0;k<=15;k++){
if(k+i-8>n)break;
if(k+i-8<0||dp[i][j][k]>1e9)continue;
if(j&1){
dp[i+1][j>>1][k-1]=min(dp[i+1][j>>1][k-1],dp[i][j][k]);
}
else{
ll lst=1e18;
for(int l=0;l<=7&&l+i<=n;l++){
if(l>lst)break;
if(j&(1<<l))continue;
lst=min(lst,b[i+l]+l);
dp[i][j|(1<<l)][l+8]=min(dp[i][j|(1<<l)][l+8],dp[i][j][k]+(i+k-8>0)*(t[l+i]^t[i+k-8]));
}
}
}
}
}
ans=1e18;
for(int i=0;i<=8;i++)ans=min(ans,dp[n][1][i]);
cout<<ans<<"\n";
}
return 0;
}