2 solutions

  • 0
    @ 2024-9-1 12:19:28

    忘记重置n的值了,警示后人

    using namespace std;
    
    int n, a[111], cnt, len;
    bool v[111];
    
    bool dfs(int sum, int leng, int last){
    	if(sum == cnt) return true;
    	if(leng == len) return dfs(sum + 1, 0, 0); 
    	
    	int val = 0;
    	for(int i=last;i<n;i++){
    		if(v[i]) continue;
    		if(a[i] == val) continue;
    		if(leng + a[i] > len) continue; 
    		v[i] = 1;
    		if(dfs(sum, leng + a[i], i + 1)) return true; 
    		v[i] = 0;
    		val = a[i];
    		if(!leng || len == leng + a[i]) return false;
    	}return false;
    }
    
    int main(){
    	while(cin>>n){
    		if(!n) return 0;
    		int maxx = 0, sum = 0, tot = 0;
    		
    		for(int i=0;i<n;i++){
    			int x;
    			cin>>x;
    			if(x>50) continue;
    			sum += x;
    			a[tot++] = -x;
    			maxx = max(maxx, x);
    		}
    		n = tot; // 忘记重置n的值了
    		sort(a, a + n);
    		for(int i=0;i<n;i++) a[i] = -a[i];
    		
    		for(len=maxx;len<=sum;len++){
    			if(sum % len) continue;
    			cnt = sum / len;
    			memset(v, 0, sizeof v); 
    			if(dfs(0, 0, 0)) break;
    		} cout<<len<<endl;
    	}
    } 
    
    
    • 0
      @ 2024-8-28 23:22:59
      #include <bits/stdc++.h>
      using namespace std;
      int a[100], v[100], n, len, cnt;
      
      // 正在拼第stick根原始木棒(已经拼好了stick-1根)
      // 第stick根木棒的当前长度为cab
      // 拼接到第stick根木棒中的上一根小木棍为last
      bool dfs(int stick, int cab, int last) {
      	// 所有原始木棒已经全部拼好,搜索成功
      	if (stick > cnt) return true;
      	// 第stick根木棒已经拼好,去拼下一根
      	if (cab == len) return dfs(stick + 1, 0, 1);
      	int fail = 0; // 剪枝
      	// 剪枝(1):小木棍长度递减(从last开始枚举)
      	for (int i = last; i <= n; i++)
      		if (!v[i] && cab + a[i] <= len && fail != a[i]) {
      			v[i] = 1;
      			if (dfs(stick, cab + a[i], i + 1)) return true;
      			fail = a[i];
      			v[i] = 0; // 还原现场
      			if (cab == 0 || cab + a[i] == len) return false; // 剪枝
      		}
      	return false; // 所有分支均尝试过,搜索失败
      }
      
      int main() {
      	while (cin >> n && n) {
      		int sum = 0, val = 0, m = 0;
      		for (int i = 1; i <= n; i++) {
      			int x;
      			scanf("%d", &x);
      			if (x <= 50) {
      				a[++m] = x;
      				sum += a[m];
      				val = max(val, a[m]);
      			}
      		}
      		n = m;
      		sort(a + 1, a + n + 1);
      		reverse(a + 1, a + n + 1); 
      		for (len = val; len <= sum; len++) {
      			if (sum % len) continue;
      			cnt = sum / len; // 原始木棒长度为len,共cnt根
      			memset(v, 0, sizeof(v));
      			if (dfs(1, 0, 1)) break;
      		}
      		cout << len << endl;
      	}
      }
      
      • 1

      Information

      ID
      483
      Time
      1000ms
      Memory
      256MiB
      Difficulty
      10
      Tags
      # Submissions
      12
      Accepted
      2
      Uploaded By