HDU 5115 (2014ACM/ICPC亚洲区北京站) D题(Dire Wolf)
题目传送门
>设dp[i][j]为杀掉区间i到j之间的狼需要付出的最小代价,那么dp[i][j]=min{dp[i][k-1]+dp[k+1][j]+a[k]+b[i-1]+b[j+1]}
##Java代码 ``` import java.io.*; import java.util.*; class MyInputStream extends InputStream { public BufferedInputStream bis = new BufferedInputStream(System.in); public int read() throws IOException { int i; while ((i = bis.read()) < 48) if (i == -1) return -1; int temp = 0; while (i > 47) { temp = temp * 10 + i - 48; i = bis.read(); } return temp; } } public class hdu_5115 { static final int N=500; static long dp[][]=new long[N][N]; static int a[]=new int[N]; static int b[]=new int[N]; static int inf=(int)1e9; private static MyInputStream cin; public static void main(String[] args) throws IOException{ cin = new MyInputStream(); int T=cin.read(); int ca=0; while(0!=T--){ int n=cin.read(); for(int i=1;i<=n;i++){ a[i]=cin.read(); } for(int i=1;i<=n;i++){ b[i]=cin.read(); } a[0]=a[n+1]=0; b[0]=b[n+1]=0; for(int i=1;i<=n;i++){ Arrays.fill(dp[i],inf); dp[i][i]=a[i]+b[i-1]+b[i+1]; } dp[0][0]=0; for(int len=0;len<=n;len++) for(int i=1;i<=n;i++){ int j=i+len; if(j>n) break; for(int k=i;k<=j;k++){ if(k-1j) dp[k+1][j]=0; dp[i][j]=Math.min(dp[i][k-1]+dp[k+1][j]+a[k]+b[i-1]+b[j+1],dp[i][j]); } } System.out.println("Case #"+(++ca)+": "+dp[1][n]); } } } ```
##C++代码 ``` #include
int main(){
int T=read();
int ca=0;
while(0!=T--){
int n=read();
for(int i=1;i<=n;i++){
a[i]=read();
}
for(int i=1;i<=n;i++){
b[i]=read();
}
a[0]=a[n+1]=0;
b[0]=b[n+1]=0;
for(int i=1;i<=n;i++){
fill(dp[i],dp[i]+N,inf);
dp[i][i]=a[i]+b[i-1]+b[i+1];
}
dp[0][0]=0;
for(int len=0;len<=n;len++)
for(int i=1;i<=n;i++){
int j=i+len;if(j>n) break;
for(int k=i;k<=j;k++){
if(k-1<i) dp[i][k-1]=0;
if(k+1>j) dp[k+1][j]=0;
dp[i][j]=min(dp[i][k-1]+dp[k+1][j]+a[k]+b[i-1]+b[j+1],dp[i][j]);
}
}
cout<<"Case #"<<(++ca)<<": "<<dp[1][n]<<endl;
}
return 0;
}