终于在任重而道不远的形势的逼迫下,拾起了自己畏惧的动态规划。
于是开始从最简单的题做起。
题目链接:https://www.luogu.org/problemnew/show/P1164
思路:
第一眼,搜索。
第二眼,奇怪的dp。
第三眼,完全背包。
搜索(较容易实现):
#include <bits/stdc++.h> const int MAXN=100050; using namespace std; int n,m,ans,a[MAXN]; bool vis[MAXN]; void dfs(int x,int y){ if(y==0){ ans++; return ; } for(int i=x+1;i<=n;i++){ if(!vis[i]&&y>=a[i]){ vis[i]=true; dfs(i,y-a[i]); vis[i]=false; } } } int main(){ ios::sync_with_stdio(false); cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; dfs(0,m); printf("%d ",ans); return 0; }
奇怪的dp(非正确做法):
自己想的一种"dp"做法。
设$f[x]$表示能表示出$x$的所有方案数,然后用乘法原理搞一下。
主体部分:
for(int i=1;i<=n;i++) cin>>a[i],f[a[i]]++,Max=max(Max,f[a[i]]); //init(); for(int i=1;i<=m;i++){ for(int j=1,l=i-1;j<=l;j++,l--){ if(j!=l) f[i]+=f[j]*f[l]; else f[i]+=b[i-1]; } }
其中$b[i]$表示$i-1$的阶乘值,这个显然能推出来。
但是具有后效性,故是一个完全错误的想法。
完全背包:
updating...