首页 > 代码库 > 【Vijos1222】等值拉面(DP)
【Vijos1222】等值拉面(DP)
题意:有N个数对(a[i],b[i])
每次可以把(x,y)变成(x+a[i],y+b[i])或(x+b[i],x+a[i]),后者称为交换一次
求使abs(x-y)最小时的最小交换次数
n<=1000 1<=a[i],b[i]<=6
思路:设dp[i,j]为前i个数对,使x-y=j时的最小交换次数 转移即可
1 const oo=100000; 2 var dp:array[0..1,-6100..6100]of longint; 3 a,b:array[1..1100]of longint; 4 n,i,v,j,t,ans:longint; 5 6 function min(x,y:longint):longint; 7 begin 8 if x<y then exit(x); 9 exit(y); 10 end; 11 12 begin 13 14 readln(n); 15 for i:=1 to n do read(a[i],b[i]); 16 v:=0; 17 fillchar(dp[v],sizeof(dp[v]),$1f); 18 dp[0,0]:=0; 19 for i:=0 to n-1 do 20 begin 21 v:=1-v; fillchar(dp[v],sizeof(dp[v]),$1f); 22 for j:=-5*i to 5*i do 23 if dp[1-v,j]<oo then 24 begin 25 t:=j+a[i+1]-b[i+1]; 26 dp[v,t]:=min(dp[v,t],dp[1-v,j]); 27 t:=j+b[i+1]-a[i+1]; 28 dp[v,t]:=min(dp[v,t],dp[1-v,j]+1); 29 end; 30 // print; 31 end; 32 ans:=oo; 33 for i:=0 to 5*n do 34 begin 35 ans:=min(ans,min(dp[v,i],dp[v,-i])); 36 if ans<oo then break; 37 end; 38 writeln(ans); 39 40 end.
【Vijos1222】等值拉面(DP)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。