[Luogu1846] [NOIP2012模擬10.22] 遊戲 [dp]
阿新 • • 發佈:2018-12-16
先
顯然數比較少的那一列,每個數都應該屬於不同的被運算元集合 考慮上面那一列怎麼做。
不拆, 拆,。
可以發現不拆總會比拆答案要大
要用相信很容易看出來( 一種自然的思路是考慮把數選入集合。 如果兩個序列數的個數相等,當然一個對著一個放進去就是最後的答案 否則就把長的那一列提出來考慮。 也就是考慮長的那一列的第個數是否選入第個集合。 從集合中選入元素,那麼單個集合可以分為選一個或者選多個。 用狀態表示選到長的一列第個數,已經有個集合,此時的最小答案。 於是 其中,轉移過來代表集合裡面就只有一個數。 而從則裡面有多個數。 其中就是集合還沒確定,而是確定了集合 這算是把樸素方程進行了一種懶處理
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
int N,M;
long long A[2005]={},B[2005]={};
long long F[2005][2005]={};
int main()
{
cin>>N>>M;
for(int i=1;i<=N;++i)cin>>A[i],--A[i];
for(int i=1;i<=M;++i)cin>>B[i],--B[i];
for(int i=0;i<=N;++i)
for(int j=0;j<=M;++j)
F[i][j]=2147483647147483647ll;
F[0][0]=0;
for(int i=1;i<=N;++i)
for(int j=1;j<=M;++j)
F[i][j]=min(min(F[i][j-1],F[i-1][j]),F[i-1][j-1])+A[i]*B[j];
cout<<F[N][M];
return 0;
}