写这篇文章呢,有个很邪恶的目的,就是提高博客的访问量——据我所知“POJ 1011”这个关键词似乎非常极其的热门——是不是?
当时我做这题的时候的确就写了下面这么长的代码,不过你读一遍就会发现 3/4 的内容都被注释掉了,那些内容多少能说明我的思想,而剩下来的那部分是可以 AC 的。
PS. 我真的不喜欢全局变量。
PPS. 以后这里不会再放ACM的代码了;感兴趣的话可以等河蟹在睡觉的某天访问 hi-if.blogspot.com 看看。
- #if 1 // includes
- #include <memory.h>
- #include <iostream>
- #include <algorithm>
- #include <functional>
- using namespace std;
- #endif // for folding
- #define POJ_IS_STUPID 0
- #if POJ_IS_STUPID
- #if 0
- struct state { //里面这些东西不一定都用得着倒是了
- int sticks[51]; // 长度为 i 的木棍有 sticks[i] 个。
- int figures[51]; // 各种长度
- int nfigures;
- int length;
- int target;
- int remained;
- int max;
- int min;
- int sum;
- };
- template <class T>
- size_t inv_bin_search(T* array, size_t len, T const& n) {
- size_t a=0,b=len,m1,m2=-1;
- for (m1=(a+b)>>1;m1!=m2;) {
- m2=m1;
- if (array[m1]==n) return m1;
- else if (array[m1]>n) a=m1;
- else b=m1;
- m1=(a+b)>>1;
- }
- if (array[m1]<n) return m1;
- else return m1-1;
- }
- bool match(state& st, int target) {
- bool first=(target==st.target);
- int i,*j;
- if (target>st.max) {
- //for(i=st.max;i>=st.min;--i){
- for (j=st.figures;i=*j;++j) {
- if (st.sticks[i]) {
- --st.sticks[i];
- st.sum-=i;
- if (match(st,target-i))
- return true;
- st.sum+=i;
- ++st.sticks[i];
- if (first)
- return false;
- }
- }
- return false;
- } else if (target<st.min) {
- return false;
- } else if (target>st.sum) {
- return false;
- } else if (target==st.sum) {
- return true;
- }
- if (st.sticks[target]) {
- --st.sticks[target];
- st.sum-=target;
- if (--st.remained==0) return true;
- if (match(st,st.target))
- return true;
- ++st.remained;
- st.sum+=target;
- ++st.sticks[target];
- return false;
- }
- for (j=st.figures+inv_bin_search<int>(st.figures,st.nfigures,target);
- *j>=target&&*j;++j);
- for (;i=*j;++j) {
- if (st.sticks[i]) {
- --st.sticks[i];
- st.sum-=i;
- if (match(st,target-i))
- return true;
- st.sum+=i;
- ++st.sticks[i];
- if (first)
- return false;
- }
- }
- return false;
- }
- int main() {
- for (state s={{0},{0},0,0};cin>>s.length&&s.length;) {
- s.sum=0;
- s.max=0;
- s.min=100;
- int x,i,j,n=0;
- bool succeed=false;
- for (i=0;i<=50;++i)
- s.sticks[i]=0;
- for (i=0;i<s.length;++i) {
- cin>>x;
- if (!s.sticks[x]) {
- s.figures[n]=x;
- ++n;
- }
- ++s.sticks[x];
- s.sum+=x;
- if (x>s.max) s.max=x;
- if (x<s.min) s.min=x;
- }
- s.figures[n]=0;
- s.nfigures=n;
- sort(s.figures,s.figures+n,greater<int>());
- for (j=s.max;j<=s.sum/2;++j) {
- if (s.sum%j==0) {
- s.target=j;
- s.remained=s.sum/j;
- if ( match(s,j) ) {
- cout<<j<<endl;
- succeed=true;
- break;
- }
- }
- }
- if (!succeed)
- cout<<s.sum<<endl;
- }
- return 0;
- }
- #else
- struct state { //里面这些东西不一定都用得着倒是了
- int sticks[51]; // 长度为 i 的木棍有 sticks[i] 个。
- int figures[51]; // 各种长度
- int nfigures;
- int length;
- int target;
- int remained;
- int max;
- int min;
- int sum;
- };
- template <class T>
- size_t inv_bin_search(T* array, size_t len, T const& n) {
- size_t a=0,b=len,m1,m2=-1;
- for (m1=(a+b)>>1;m1!=m2;) {
- m2=m1;
- if (array[m1]==n) return m1;
- else if (array[m1]>n) a=m1;
- else b=m1;
- m1=(a+b)>>1;
- }
- if (array[m1]<n) return m1;
- else return m1-1;
- }
- bool match(state& st, int target) {
- int (&sticks)[51]=st.sticks;
- int (&figures)[51]=st.figures;
- int &sum=st.sum;
- int &remained=st.remained;
- bool first=(target==st.target);
- int i,*j;
- if (target>st.max) {
- //for(i=st.max;i>=st.min;--i){
- for (j=figures;i=*j;++j) {
- if (sticks[i]) {
- --sticks[i];
- sum-=i;
- if (match(st,target-i))
- return true;
- sum+=i;
- ++sticks[i];
- if (first)
- return false;
- }
- }
- return false;
- } else if (target<st.min) {
- return false;
- } else if (target>st.sum) {
- return false;
- } else if (target==st.sum) {
- return true;
- }
- if (sticks[target]) {
- --sticks[target];
- sum-=target;
- if (--remained==0) return true;
- if (match(st,st.target))
- return true;
- ++remained;
- sum+=target;
- ++sticks[target];
- return false;
- }
- for (j=figures+inv_bin_search<int>(figures,st.nfigures,target);
- *j>=target&&*j;++j);
- for (;i=*j;++j) {
- if (sticks[i]) {
- --sticks[i];
- sum-=i;
- if (match(st,target-i))
- return true;
- sum+=i;
- ++sticks[i];
- if (first)
- return false;
- }
- }
- return false;
- }
- int main() {
- for (state s={{0},{0},0,0};cin>>s.length&&s.length;) {
- s.sum=0;
- s.max=0;
- s.min=100;
- int x,i,j,n=0;
- bool succeed=false;
- for (i=0;i<=50;++i)
- s.sticks[i]=0;
- for (i=0;i<s.length;++i) {
- cin>>x;
- if (!s.sticks[x]) {
- s.figures[n]=x;
- ++n;
- }
- ++s.sticks[x];
- s.sum+=x;
- if (x>s.max) s.max=x;
- if (x<s.min) s.min=x;
- }
- s.figures[n]=0;
- s.nfigures=n;
- sort(s.figures,s.figures+n,greater<int>());
- for (j=s.max;j<=s.sum/2;++j) {
- if (s.sum%j==0) {
- s.target=j;
- s.remained=s.sum/j;
- if ( match(s,j) ) {
- cout<<j<<endl;
- succeed=true;
- break;
- }
- }
- }
- if (!succeed)
- cout<<s.sum<<endl;
- }
- return 0;
- }
- #endif
- #else
- #if 0 //以前的
- struct state { //不想用全局变量, 又不应该在递归的函数中使用太多参数, so...
- int sticks[65];
- bool thereis[65];
- int length;
- int sum;
- int max;
- int target;
- };
- bool dfs(state& st, int target, int nremained, int begin=0) {
- if ( target==0 ) {
- if ( nremained==1 )
- return true;
- else
- return dfs(st,st.target,nremained-1,1);
- } else {
- if (begin>=st.length)
- return false;
- bool first=(target==st.target),last=false;
- for (int i=begin;i<st.length;++i) {
- if (!st.thereis[i])
- continue;
- if (st.sticks[i]>target) {
- // if(first){return false;}//impossible
- continue;
- }
- st.thereis[i]=false;
- last=(st.sticks[i]==target);
- if (dfs(st,target-st.sticks[i],nremained,i+1)) {
- return true;
- } else {
- st.thereis[i]=true;
- if ( first||last ) return false;
- for (;st.sticks[i]==st.sticks[++i];);
- --i;
- }
- }
- }
- return false;
- }
- int main() {
- for (state s;cin>>s.length&&s.length;) {
- s.max=s.sum=0;
- int x;
- bool succeed=false;
- for (int i=0;i<s.length;++i) {
- cin>>x;
- s.sticks[i]=x;
- s.sum+=x;
- if (x>s.max) s.max=x;
- s.thereis[i]=true;
- }
- sort(s.sticks,s.sticks+s.length,greater<int>());
- s.sticks[s.length]=0;
- s.thereis[s.length]=false;
- for (int j=s.max;j<=s.sum/2;++j) {
- if (s.sum%j==0) {
- s.target=j;
- if ( dfs(s,j,s.sum/j) ) {
- cout<<j<<endl;
- succeed=true;
- break;
- }
- }
- }
- if (!succeed)
- cout<<s.sum<<endl;
- }
- return 0;
- }
- #else
- int g_sticks[65];
- bool g_used[65];
- int g_length;
- int g_sum;
- int g_max;
- int g_min;
- int g_target;
- bool dfs(int target, int remained, int begin) {
- if( target<g_min||begin>=g_length )
- return false;
- if (target==g_target) { //第一根
- for (int i=begin;i<g_length;++i) {
- if (g_used[i])
- continue;
- g_used[i]=true;
- if(g_sticks[i]==target){ // 最后一根
- if(remained==1)
- return true;
- if(dfs(g_target , remained-1, 1))
- return true;
- g_used[i]=false;
- return false;
- } else if (dfs(target-g_sticks[i],remained,i+1))
- return true;
- g_used[i]=false;
- return false;
- }
- } else {
- for (int i=begin;i<g_length;++i) {
- if (g_used[i])
- continue;
- if (g_sticks[i]>target)
- continue;
- g_used[i]=true;
- if(g_sticks[i]==target){ // 最后一根
- if(remained==1)
- return true;
- if(dfs(g_target , remained-1, 1))
- return true;
- g_used[i]=false;
- return false;
- }
- if (dfs(target-g_sticks[i],remained,i+1))
- return true;
- g_used[i]=false;
- for(;g_sticks[i]==g_sticks[i+1];++i);
- }
- }
- return false;
- }
- //#include <fstream>
- int main() {
- //ifstream fin("test.txt");
- istream& xin=cin;//fin;
- for (;xin>>g_length&&g_length;) {
- int x;
- bool succeed=false;
- g_max=g_sum=0;
- g_min=1000;
- for (int i=0;i<g_length;++i) {
- xin>>x;
- g_sticks[i]=x;
- g_sum+=x;
- if (x>g_max) g_max=x;
- if (x<g_min) g_min=x;
- g_used[i]=false;
- }
- sort(g_sticks,g_sticks+g_length,greater<int>());
- g_sticks[g_length]=0;
- g_used[g_length]=true;
- for (int j=g_max;j<=g_sum/2;++j) {
- if (g_sum%j==0) {
- g_target=j;
- if ( dfs(j,g_sum/j,0) ) {
- cout<<j<<endl;
- succeed=true;
- break;
- }
- }
- }
- if (!succeed)
- cout<<g_sum<<endl;
- }
- return 0;
- }
- #endif
- #endif