SRM497 div2 hard

めっちゃ時間がかかったけど自分で解法を見つけた。
まずinsertは必要ない。(deleteで代用できる)
次にSを前半と後半に分け(最大50通り)その2つを等しくするための最小値を
求める。
先頭同士が同じならその先頭は無視して次を考える

if(s[i]==t[j])
DP[i][j]=DP[i+1][j+1]

違うならどちらかをdeleteもしくはどちらかをchangeする。
changeするならどちらをchangeしても同じなので

else
DP[i][j]=min(DP[i+1][j],min(DP[i][j+1],DP[i+1][j+1])+1

となる

#include <cstring>
#include <string>

using namespace std;

class MakeSquare
{
	public:

		string s,t;
		int n,m;
		int DP[50][50];

		int calc()
		{
			for(int i=n;0<=i;i--)
				for(int j=m;0<=j;j--)
				{
					if(i==n || j==m)
						DP[i][j]=n+m-i-j;
					else if(s[i]==t[j])
						DP[i][j]=DP[i+1][j+1];
					else
						DP[i][j]=min(DP[i+1][j],min(DP[i][j+1],DP[i+1][j+1]))+1;
				}
			return DP[0][0];
		}

		int minChanges(string S)
		{
			int ans=(1<<28);
			int Sn=S.size();
			for(int i=0;i<Sn;i++)
			{
				s=S.substr(0,i),t=S.substr(i,Sn-i);
				n=i,m=Sn-i;
				ans=min(ans,calc());
			}
			return ans;
		}
};