荣誉版主
- 积分
- -2403
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2010-5-4
- 最后登录
- 1970-1-1
|
应为有负数的存在,一开始还以为是NP复杂,没想到DP可以记录最大值,同时一样可以记录最小值。对于加号来说,两边最大和最大,两边最小和最小。对于乘来说,两边最大最小的4种组合求乘积的最大最小值...
- struct OPERATION
- {
- char cOpr;
- int nLft;
- int nRgt;
- OPERATION(int l = 0, int r = 0, char op = 0)
- {
- nLft = l;
- nRgt = r;
- cOpr = op;
- }
- };
- int GetNoneNegNum(const char*& pIter)
- {
- int nRet = -1;
- while (*pIter == ' ') pIter++;
- while (*pIter >= '0' && *pIter <= '9')
- {
- if (nRet < 0) nRet = 0;
- nRet = nRet*10 + *pIter - '0';
- pIter++;
- }
- return nRet;
- }
- char GetOperator(const char*& pIter)
- {
- while (*pIter == ' ') pIter++;
- if (*pIter != '-' && *pIter != '+' && *pIter != '*')
- return 0;
-
- char cRet = *pIter++;
- return cRet;
- }
- bool Parse(const char* szString, vector<OPERATION>& vec, int nLft)
- {
- if (NULL == szString) return false;
- if (vec.empty())
- nLft = GetNoneNegNum(szString);
- if (nLft < 0) return false;
- while (*szString == ' ') szString++;
- if ('\0' == *szString) return true;
- int cOpr = GetOperator(szString);
- if (0 == cOpr) return false;
- int nRgt = GetNoneNegNum(szString);
- if (nRgt < 0) return false;
- vec.push_back(OPERATION(nLft, nRgt, cOpr));
- return Parse(szString, vec, nRgt);
- }
- int Calc(int l, char cOpr, int r)
- {
- if ('+' == cOpr) return l+r;
- if ('-' == cOpr) return l-r;
- if ('*' == cOpr) return l*r;
- return 0;
- }
- bool GetMaxResult(const char* szString, int& res)
- {
- vector<OPERATION> recs;
- if (!Parse(szString, recs, 0))
- return false;
- struct RECORD
- {
- int nMax;
- int nMin;
- };
- int nSize = recs.size();
- RECORD** pRec = new RECORD*[nSize];
- for (int i = 0; i < nSize; i++)
- pRec[i] = new RECORD[nSize];
- for (int i = 0; i < nSize; i++)
- pRec[i][i].nMax = pRec[i][i].nMin = Calc(recs[i].nLft, recs[i].cOpr, recs[i].nRgt);
- for (int i = 1; i < nSize; i++)
- for (int j = 0; j + i < nSize; j++)
- {
- int nMax = 0;
- int nMin = 0;
- for (int k = 0; k <= i; k++)
- {
- int nLMax, nLMin, nRMax, nRMin;
- if (0 == k)
- nLMin = nLMax = recs[j].nLft;
- else
- {
- nLMax = pRec[j][j+k-1].nMax;
- nLMin = pRec[j][j+k-1].nMin;
- }
- if (i == k)
- nRMin = nRMax = recs[j+i].nRgt;
- else
- {
- nRMax = pRec[j+k+1][j+i].nMax;
- nRMin = pRec[j+k+1][j+i].nMin;
- }
- int nTmpMax = 0;
- int nTmpMin = 0;
- char cOp = recs[j+k].cOpr;
- if ('+' == cOp)
- {
- nTmpMax = nLMax + nRMax;
- nTmpMin = nLMin + nRMin;
- }
- if ('-' == cOp)
- {
- nTmpMax = nLMax - nRMin;
- nTmpMin = nRMin + nLMax;
- }
- if ('*' == cOp)
- {
- nTmpMax = max(max(nLMax*nRMax, nLMax*nRMin), max(nLMin*nRMin, nLMin*nRMax));
- nTmpMin = min(min(nLMax*nRMax, nLMax*nRMin), min(nLMin*nRMin, nLMin*nRMax));
- }
- nMax = nMax > nTmpMax ? nMax : nTmpMax;
- nMin = nMin < nTmpMin ? nMin : nTmpMin;
- }
- pRec[j][j+i].nMax = nMax;
- pRec[j][j+i].nMin = nMin;
- }
- res = pRec[0][nSize-1].nMax;
- for (int i = 0; i < nSize; i++)
- delete []pRec[i];
- delete []pRec;
- return true;
- }
复制代码 |
|