Proven POJ 1014-mode optimization trim with partial recursion errors

Source: Internet
Author: User

This problem is present to do. I find that even a workable problem is not necessarily correct.

Most of the data is weak because of the subject.

id=1014 ">poj 1014 Dividing

The main idea: there are 6 of stones, weights of 1 2 3 4 5 6, asked to enter the number of each heap, to be able to divide the stone so that the two piles of value the same.


There are two ways of doing this on the internet, with the wrong version number. But can also be AC.

At first, it made me wait for the rookie. The code is concise, but the proof of correctness cannot be obtained

The next step is to prove the error of the two methods.

1. Multi-pack

 #include <map> #include <string> #include <iostream> #include < stack> #include <algorithm> #include <math.h>using namespace std; #define MAXN 100+60000int V[maxn];int a[ Maxn/3];int B[7] = {1, a, a, a, a, a, 10};int n,t,n,sum;/*int direct[4][2]={-1,0,1,0,0,-1,0,1}; int dp[210][210][210];*/int max (int a,int b) {return a>b?a:b;} int main () {int I,j,k,flag,casenum;casenum=0;while (1) {Casenum++;memset (v,0,sizeof (v)); Flag=0;sum=0;n=0;for (i=0;i <6;i++) {scanf ("%d", &k), if (k) flag=1;k=k%b[i+1];sum+=k* (i+1); for (j=1;j<=k;j++) a[n++]=i+1;} if (flag==0) break;if (sum&1) {printf ("Collection #%d:\ncan ' t be divided.\n\n", casenum); continue;} Flag=0;sum/=2;v[0]=1;for (i=0;i<n;i++) {for (j=sum;j>=a[i];j--) {v[j]+= v[j-a[i]];if (V[sum]) {flag=1;break;} if (flag) break;}} if (flag) printf ("Collection #%d:\ncan be divided.\n\n", casenum); elseprintf ("Collection #%d:\ncan ' t is divided.\n\n", Casenum);} return 0;} 

States are defined by several methods that can be transferred here.


K=K%B[I+1];

This sentence is an optimization, initially seen, considered very wonderful, but does not understand why it can be done.

Later proved to be wrong, which proves for example the following:

Modulo optimization is wrong, the following proves to optimize a bunch of situations
1.1a+2b+3c+4d+5e+6f
2.60*m*t+ 1a+2b+3c+4d+5e+6f (T is the number of stones, M is the weight of a heap of stones)
Proving that optimization is correct is proof that 1 is a 2-type is sufficient and necessary
When 1 is established, Nature gets 2 established (60 can be divided into two piles)
When 2 was established there were two cases,
In the first case, 2 can be divided, 1 of the parts themselves can be divided, then 60*m*t this part of the original is good
A different situation. 2 can be divided. 1 of the part itself is not divided, it is necessary to divide the 60*m*t part of the two talents feasible
It is not feasible to make a split out of it, but it is not ruled out that every heap optimization will come across a situation that happens to be feasible.
Finally, give a sample to everyone
1.0 0 0 0 5---0 0 0 0 6 5 ture
2.0 0 0 0 1, 0 0 0 0 0 1 fault

Optimization or 2-based optimization (1,2,4,..., 2^ (k-1), n[i]-2^k+1, and K is the largest integer that satisfies n[i]-2^k+1>0.

Like what. Suppose N[i] is 13. Divide such items into four items with coefficients of 1,2,4,6 respectively)

    1. Why are some transfer equations on the net V[i][j]=max (V[i-1][j],v[j-a[i]]+a[i])?
    2. A : Being able to see J-a[i] shows a complementary state with a[i, in fact J, from all J angles. It hasn't changed, it's v[0]=0.

2. Dfs version number (reproduced in Daniel blog)

Memory time//452k 0MS/*dfs*/#include <iostream>using namespace Std;int n[7];  The number of items valued as I int sumvalue;  Total value of goods int halfvalue;    The value of the goods is divided by bool flag; Mark can divide sumvaluevoid DFS (int value,int pre) {if (flag) return;if (value==halfvalue) {Flag=true;return;} for (int i=pre;i>=1;i--) {if (N[i]) {if (value+i<=halfvalue) {n[i]--;D fs (value+i,i), if (flag) break;}}} return;} int main (int i) {int test=1;while (cin>>n[1]>>n[2]>>n[3]>>n[4]>>n[5]>>n[6]) {  sumvalue=0; Item total value for (i=1;i<=6;i++) sumvalue+=i*n[i];if (sumvalue==0) break;if (sumvalue%2)//sum is odd and cannot be split evenly {cout<< " Collection # "<<test++<<": ' <<endl;cout<< "Can ' t be divided."    <<endl<<endl; Note that there is a blank line continue;} Halfvalue=sumvalue/2;flag=false;dfs (0,6); if (flag) {cout<< "Collection #" <<test++<< ': ' << endl;cout<< "Can be divided." <<endl<<endl;continue;} else{cout<< "Collection #" <<test++<< ': ' <<endl;cout<< ' Can ' t be diviDed. " <<endl<<endl;continue;}} return 0;}
This version number is very well written by DFS, amongThis depth priority has two merits to ponder

1. Why no backtracking. Instead, the quantity n[i]--is deducted directly;

A: Two people choose, it must be divided into two parts, assuming that the nearest number is not selected, the remaining is closer

2. Choose from big to small?

A : There may be several small can be directly replaced with a large number of

--------------------------------------------------------------------------------------------------------------- -------------------

But there is a problem.

Its essence is to use the greedy strategy, but can not meet some "jumping" requirements

eg:0 0 3 0 3 1 The number that needs to be selected is discontinuous, and in fact it has to be backtracking.

To avoid this problem can use this version number

void divide (int cur_value, int cur_index)  {          //Set Break point          if (flag)                  return;          if (Cur_value = = Half_value)          {                  flag = true;                  return;          }          if (Cur_value > Half_value | | cur_index >= max_index)                  return;          Divide (Cur_value+array[cur_index], cur_index+1);          Divide (Cur_value, cur_index+1);  }  


seem to learn or be cautious, the process of believing

Copyright notice: This article blog original articles, blogs, without consent, may not be reproduced.

Proven POJ 1014-mode optimization trim with partial recursion errors

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.