双塔DP。
#include<cstdio> #include<cstring> #include<queue> #include<string> #include<algorithm> #include<map> #include<iostream> using namespace std; const int maxn=100+50; int T,n; int dp[maxn][2*maxn]; int a[maxn],b[maxn]; void init() { for(int i=1;i<=n;i++) for(int j=0;j<=200;j++) dp[i][j]=0x7fffffff; } void read() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]); } void work() { dp[1][a[1]+100]=dp[1][0-b[1]+100]=0; for(int i=2;i<=n;i++) { for(int j=0;j<=200;j++) { if(dp[i-1][j]==0x7fffffff) continue; int tmp=j-100; if(tmp>=0) { dp[i][a[i]+100]=min(dp[i][a[i]+100],dp[i-1][j]+tmp); if(b[i]>=tmp) dp[i][tmp-b[i]+100]=min(dp[i][tmp-b[i]+100],dp[i-1][j]+tmp); else if(b[i]<tmp) dp[i][tmp-b[i]+100]=min(dp[i][tmp-b[i]+100],dp[i-1][j]+b[i]); } else if(tmp<0) { tmp=-tmp; if(dp[i-1][j]+tmp<dp[i][0-b[i]+100]) dp[i][0-b[i]+100]=min(dp[i][0-b[i]+100],dp[i-1][j]+tmp); if(a[i]<=tmp) dp[i][a[i]-tmp+100]=min(dp[i][a[i]-tmp+100],dp[i-1][j]+a[i]); else if(a[i]>tmp) dp[i][a[i]-tmp+100]=min(dp[i][a[i]-tmp+100],dp[i-1][j]+tmp); } } } int ans=0x7fffffff; for(int j=0;j<=200;j++) { if(dp[n][j]==0x7fffffff) continue; ans=min(ans,dp[n][j]+abs(j-100)); } printf("%d\n",ans); } int main() { scanf("%d",&T); while(T--) { read(); init(); work(); } return 0; }
时间: 2024-10-28 15:15:56