洛谷 P5664 Emiya 家今天的飯(DP)

2022-04-06 17:37:58 字數 2510 閱讀 5378

觀察題目資料範圍,發現前64pts可以用類似狀壓的思想來做(m<=3)。前84pts可以在o(n^3*m)的時間內完成。100pts需要在o(n^2*m)的時間內做。

總述:注意總的初始化,初始化要為1,因為後面有乘的操作,最後的時候再將那個多餘的1減去。

64pts:

設f[i][j][k][q]表示到第i行,第1列選了j個,第2列選了k個,第3列選了q個。

轉移有四種情況:1.不選  2.選的是第一列的  3.選的是第二列的  4.選的是第三列的

則f[i][j][k][q]=f[i-1][j][k][q]+f[i-1][j-1][k][q]*a[i][1]+f[i-1][j][k-1][q]*a[i][2]+f[i-1][j][k][q-1]*a[i][3]

因為根據題意,要求j<=(j+k+q)/2,k<=(j+k+q)/2,q<=(j+k+q)/2,化簡為:

j<=k+q,k<=j+q,q<=j+k。只有滿足這個,ans+=f[n][j][k][q]。

**:

1 #include2 #include3

using

namespace

std;

4 typedef long

long

ll;5

const ll mod=998244353;6

const

int n=50;7

ll f[n][n][n][n],a[n][n];

8ll n,m,ans;

9int

main()23}

24for(int i=0;i<=n/2;i++)

25for(int j=0;j<=n/2;j++)

26for(int k=0;k<=n/2;k++)

29 printf("

%lld\n

",ans-1

);30

return0;

31 }

64pts

84pts:

列舉列數j,設f[i][k][q]表示到第i行,第j列一共選了k個,其餘所有列一共選了q個。

轉移有三種情況:1.不選  2.選的是第j列的  3.選的不是第j列的

則f[i][k][q]=f[i-1][k][q]+f[i-1][k-1][q]*a[i][j]+f[i-1][k][q-1]*(sum[i]-a[i][j])

然後運用容斥原理,用總的方案數減去不符合的(k>q)方案數即為答案。

**:

1 #include2 #include3 #include4

using

namespace

std;

5 typedef long

long

ll;6

const ll mod=998244353;7

const

int n=55

;8 ll f[n][n][n],a[n][505

],sum[n];

9 ll n,m,ans=1

,res;

10int

main()

17for(int j=1;j<=m;j++)

27for(int k=1;k<=n;k++)

31 res=(res+mod)%mod;32}

33}34 printf("

%lld\n

",(ans-res-1+mod)%mod);

35return0;

36 }

84pts

100pts:

可以發現,在84pts中的做法中,0<=k,q<=n,且k<=q,所以-n<=k-q<=n,然後便可以將上面的壓成二維:

f[i][j]表示選到了第i行,j=k-q+n,j∈[0,2n]。

則f[i][j]=f[i-1][j]+f[i-1][j-1]*a[i][j]+f[i-1][j+1]*(sum[i]-a[i][j])。

其中n+1<=j<=2*n是不符合題意的方案數,減掉即為答案。注意初始化,因為整體加了n,所以f[0][n]=1。

**:

1 #include2 #include3 #include4

using

namespace

std;

5 typedef long

long

ll;6

const ll mod=998244353;7

const

int n=105

;8 ll f[n][n<<1],a[n][2005

],sum[n];

9 ll n,m,ans=1

,res;

10int

main()

17for(int j=1;j<=m;j++)

26for(int k=n+1;k<=n*2;k++)30}

31 printf("

%lld\n

",(ans-res-1+mod)%mod);

32return0;

33 }

ac**

P5664 Emiya 家今天的飯

miku 這個題很顯然的可以從部分分推到正解 64上去就是乙個四維dp,dp i j k z 表示在第1行的時候第一行選了j個,第2行選了k個,第3行選了z個的 情況下的方案數,轉移用手就能推。只是有個小細節 include include include include define int lo...

P5664 Emiya 家今天的飯

哭了qaq這題整了12345678天,在題解和sy的部落格幫助下完成了題目qaq 給出乙個n m的矩陣,總共選k個,不能不選,要求 1.每行只能選乙個 2.每列最多選 個求出合法方案數 抽象理解一下就是這麼個東西 直接求解莫得思路,然後正難則反,我們考慮總方案數 不合法方案數 考慮沒有任何限制,我們...

P5664 Emiya家今天的飯 dp

對於n nn個方法,m mm個材料,乙個方法配對乙個材料可以做an,ma an,m 道菜。選擇k kk個配對要求 配對至少為k 1k 1 k 1每個配對的方法不同 每個材料最多用 k2 lfloor frac rfloor 2k 次 求做菜方案數 考慮容斥減去多餘方案,也就是要求乙個材料用超過一半。...