リニアDP [USACO08MAR]川クロッシングS(ロス・バレーP2904)

[USACO08MAR]川クロッシングS

タイトル説明

彼が見つけ自身が川でブロックされたときファーマージョンは彼の農場の広がり全体に(1 <= N <= 2500)彼のNの牛を放牧されています。単一いかだは、輸送のために利用可能です。

FJは、彼がすべての交差点のためのいかだに乗っていかだに牛を追加すると、それはよりゆっくりと川を横断しますということをしなければならないことを知っています。

FJ単独ラフト上にある場合、それはM分で川を横断することができる(1 <= M <= 1000)。I牛が追加されると、それはI-1牛(1頭の牛、2つとM + M_1 + M_2と、すなわち、合計M + M_1分よりも河川を横断する(1 <= M_I <= 1000)より長いM_I分かかり、など)。ファーマージョンは(より多くの牛を取得するために戻って時間を含む)川を渡っ牛の全てを取得するのにかかる最小時間を決定します。

ファーマージョンと彼のN(1 <= N <= 2,500)牛は川を意図するが、彼らは川を渡るすべてのツール、ちょうどいかだ。牛が漕ぎされていないので、プロセス全体で川を渡り、FJは常にいかだの上でなければなりません。これに基づき、各追加1についていかだ上の牛の数は、FJは反対側にいかだを取るより多くの時間を費やす必要があります。FJいかだの上に座っている人は、彼がM(1 <= M <= 1000)分を越えいかだを取る必要がある場合。I-1を運ぶ筏からの牛の数は、川を渡っいかだ前M_I(1 <= M_I <= 1000)分(牛ボード上の、ある、FJすぎを過ごすためにFJはずっと、私に増加した場合交配花M + M_1分、ボード上の2頭の牛は、時間が後など)M + M_1 + M_2分となります。それはそれの反対側にすべての牛を置くためにかかる時間まあ、少なくともFJ?もちろん、この時点人はFJが、牛の反対側から回数を引き継ぐためにいかだのバックを取る含める必要があります。

入力形式

  • 1行目:二スペースで区切られた整数:NとM

  • ライン2 ... N + 1:M_I:行I + 1は、単一の整数が含まれています

出力フォーマット

  • 1行目:ファーマージョンは川を渡っ牛の全てを取得するのにかかる最小時間。

タイトルの先頭を見ていない、私はサンプルを理解し、そして最終的にそれが取るたびにではなくM_IよりM_1、M_2、ある川を渡って牛を発見していません。

この問題は考え始めている:DP [I] [J] =分(DP [I]、[J]、DP [I-1] [JK] +和[K] + 2 * M)。

彼は、I、J出荷牛の最小時間の前に時間を表し、そして複雑さの度合いを発見したのn ^ 3、60分までの賃金。

最後に、最初の数回は、それが問題で、削除することができないため、一次元、1次元の複雑さを軽減することが低減されることが観察。

この質問は、この推論だけでなく、適切な最適化の最大の成果です。

コード:

#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=3000;
const int M=2000100;
const LL mod=1e8;
int dp[N],sum[N];
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>sum[i],sum[i]+=sum[i-1];
	for(int i=1;i<=n;i++) dp[i]=2e9;
	dp[0]=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<=i;j++){
			dp[i]=min(dp[i],dp[i-j]+sum[j]+2*m);
		}
	}
	cout<<dp[n]-m<<endl;
	return 0;
}

60点コード:

#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=3000;
const int M=2000100;
const LL mod=1e8;
int dp[N][N],sum[N];
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>sum[i],sum[i]+=sum[i-1];
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++) dp[i][j]=2e9;
	}
	dp[0][0]=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<=n;j++){
			for(int k=0;k<=j;k++){
				dp[i][j]=min(dp[i][j],dp[i-1][j-k]+sum[k]+2*m);
			}
		}
	} 
	cout<<dp[n][n]-m<<endl;
	return 0;
}
公開された264元の記事 ウォン称賛46 ビュー10000 +

おすすめ

転載: blog.csdn.net/qq_44291254/article/details/105295050