AcWing 1205. 买不到的数目
考察:完全背包dp 或者 打表
思路:
1.如果知道公式的话,三行代码就可以解决,答案是(n-1)*(m-1)-1.前提条件是n与m互质.
2.如果不知道,可以用暴力dfs打表.先固定一个数n,再看m变化时答案如何变化.eg:当n==3,ans在m情况下每次比m-1多2.最后说不定能推出公式= =
3.还可以采用dp写法,我们设置n*m为背包容量(如果答案>n*m的话,那么ans+n*m也不能表示,那么答案是无限大的).物品的体积是n与m.f[i][j]表示在前i个数j是否能被前i个数表示.然后就可以套模板了(这证明感觉没有说服力...不知道有没有更好的)
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 const int N = 1e6+10; 7 int a[3]; 8 bool f[N]; 9 int main() 10 { 11 scanf("%d%d",&a[1],&a[2]); 12 f[0] = 1; 13 for(int i=1;i<=2;i++) 14 for(int j=a[i];j<=a[1]*a[2];j++) 15 f[j] = f[j]|f[j-a[i]]; 16 for(int i=a[1]*a[2];i>=1;i--) if(!f[i]) {printf("%d\n",i); break;} 17 return 0; 18 }
还有一个暴力dfs代码,说实话没想到怎么dfs,还是记下来吧= =
这个代码是会TLE的
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 const int N = 1e6+10; 7 bool dfs(int x,int q,int p) 8 { 9 if(!x) return true; 10 if(x>=p&&dfs(x-p,q,p)) return true; 11 if(x>=q&&dfs(x-q,q,p)) return true; 12 return false; 13 } 14 int main() 15 { 16 int n,m; 17 scanf("%d%d",&n,&m); 18 for(int i=m*n-1;i>=1;i--) 19 if(!dfs(i,m,n)) {printf("%d\n",i); break;} 20 return 0; 21 }