# 区间DP

484感觉这个有套路

``````for (int l = st; l < len-(); l++) //l：区间长度
for (int i = st; l < len-l+1; l++) // i:区间起点
{
int j = i+l-1; //j: 区间终点
for (int k = i; k < j; k++) // 状态转移过程
dp[i][j] = MAX/MIN(f[i][j], f[i][k]+f[k+1][j]+w[i][j]);
//f[i , j]= max{f[ i,k]+ f[k+1,j]+ w[i,j] }
// 这个484很像最短路/最小生成树的松弛过程
}
``````

POJ1651（石子合并类）

``````#define LL long long
#define INF 1e9
const int N = 101;
LL dp[N][N], p[N];
int vis[N];

int main()
{
int n;
scanf("%d", &n);
int minn=-INF, cur;
for (int i = 1; i <= n; i++)
scanf("%lld", &p[i]);

for (int m = 2; m <= n-1; m++) //可取区间[2, n-1]
for (int i = 2; i <= n-m+1; i++) //区间起点，第二个2数字
{
int j = m+i-1; //区间终点，最小组合区间长度3
dp[i][j] = INF;
for (int k = i; k < j; k++)
dp[i][j] = min(dp[i][j], dp[i][k] + p[i-1]*p[j]*p[k] + dp[k+1][j]);
}
printf("%I64d\n", dp[2][n]);
}
``````

POJ2955（括号合并问题）

``````const int  N = 120;
int dp[N][N];
string s;

int main()
{
while(cin >> s)
{
if(s == "end") break;
CLR(dp);
int len = s.size();
for(int i = 1; i < len; i++)
{
int k = 0;
for(int j = i; j < len; j++)
{
if(s[k]=='('&&s[j]==')' || s[k]=='['&&s[j]==']')
dp[k][j] = dp[k+1][j-1] + 2;

for(int l = k; l < j; l++)
dp[k][j] = max(dp[k][j], dp[k][l]+dp[l+1][j]);
k++;
}
}
printf("%d\n", dp[0][len-1]);
}
return 0;
}
``````

hdu4283

``````#define CLR(x) memset(x, 0, sizeof(x))
const int N = 105;
int D[N], dp[N][N];
int sum[N];

int main()
{
int T;
scanf("%d", &T);
int k = 1;
while (T--)
{
CLR(D); CLR(dp); CLR(sum);
sum[0] = 0;
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &D[i]);
sum[i] = sum[i-1] + D[i]; // get所有区间的值
}

for (int i = n; i >= 1; i--)
for (int j = i; j <= n; j++)
{
dp[i][j] = INF;
for (int d = 1; d <= j-i+1; d++)
{
int k = i+d-1;
dp[i][j] = min (dp[i][j], dp[i+1][k]+dp[k+1][j]+(d-1)*D[i]+d*(sum[j]-sum[k]));
}
}

printf("Case #%d: %d\n", k++, dp[1][n]);
}
}
``````

hdu2476

``````0：zzzzzfzzzzz
1：aaaaaaaaaaa      [0，10]
2：abbbbbbbbba   [1，9]
3：abcccccccba      [2，8]
4：abcdddddba     [3，7]
5：abcdeeedba      [4，6]
6：abcdefedba       [5]
``````

``````const int N = 105;
int dp[N][N];
char a[105], b[105];
int ans[105];

int main()
{
while (scanf("%s%s", a, b) != EOF)
{
int len = strlen(a);
for (int i = 0; i < len; i++)
{
for (int j = i; j >= 0; j--)
{
dp[j][i] = dp[j+1][i] + 1;
for (int k = j+1; k <= i; k++)
if (b[j] == b[k])
dp[j][i] = min(dp[j][i], dp[j+1][k]+dp[k+1][i]);
}
ans[i] = dp[0][i];
}
for (int i = 0; i < len; i++)
{
if (a[i] == b[i]) ans[i] = ans[i-1];
else
{
for (int j = 0; j < i; j++)
ans[i] = min(ans[i], ans[j]+dp[j+1][i]);
}
}
printf("%d\n", ans[len-1]);
}
}
``````

ZOJ3537

GG上板子上板子

``````#define CLR(x) memset(x, 0, sizeof(x))
int dp[305][305], cost[305][305];
int n, P;
struct point
{
double x, y;
} p[305], tmp[305];

bool mult(point st, point ed, point p)
{
return (st.x-p.x)*(ed.y-p.y) >= (ed.x-p.x)*(st.y-p.y);
}
bool operator < (const point &a, const point &b)
{
return a.y<b.y || (a.y==r.y && a.x<b.x);
}

int Graham(point pnt[], int n, point res[])
{
sort(pnt, pnt + n);
if (n == 0) return 0; res[0] = pnt[0];
if (n == 1) return 1; res[1] = pnt[1];
if (n == 2) return 2; res[2] = pnt[2];

int top = 1;
for (int i = 2; i < n; i++)
{
while (top && mult(pnt[i], res[top], res[top-1])) top--;
res[++top] = pnt[i];
}

int len = top;
for (int i = n - 3; i >= 0; i--)
{
while (top!=len && mult(pnt[i], res[top], res[top-1])) top--;
res[++top] = pnt[i];
}
}

int cal(int i, int j)
{
return abs((int)tmp[i].x+(int)tmp[j].x) * abs((int)tmp[i].y+(int)tmp[j].y) % P;
}

int main()
{
while (scanf("%d%d", &n, &P) != EOF)
{
CLR(p); CLR(tmp); CLR(cost);
for (int i = 0; i < n; i++)
scanf("%lf%lf", &p[i].x, &p[i].y);
if (n <= 3) printf("0\n");
else if (Graham(p, n, tmp) < n) printf("I can't cut.\n");
else
{
for (int i = 0; i < n; i++)
for (int j = i+2; j < n; j++)
cost[i][j] = cost[j][i] = cal(i, j);

for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
dp[i][j] = INF;
dp[i][(i+1)%n] = 0; //dp[i][i+1]=0(i!=n-1) dp[n-1][0]=0
}

for (int i = n-3; i >= 0; i--)
for (int j = i+2; j < n; j++)
for (int k = i+1; k <= j; k++)
dp[i][j] = min(dp[i][j], dp[i][k]+dp[k][j]+cost[i][k]+cost[k][j]);
printf("%d\n", dp[0][n-1]);
}
}
return 0;
}
``````

• 序言：七十年代末，一起剥皮案震惊了整个滨河市，随后出现的几起案子，更是在滨河造成了极大的恐慌，老刑警刘岩，带你破解...
沈念sama阅读 83,429评论 1 182
• 序言：滨河连续发生了三起死亡事件，死亡现场离奇诡异，居然都是意外死亡，警方通过查阅死者的电脑和手机，发现死者居然都...
沈念sama阅读 30,030评论 1 152
• 文/潘晓璐 我一进店门，熙熙楼的掌柜王于贵愁眉苦脸地迎上来，“玉大人，你说我怎么就摊上这事。” “怎么了？”我有些...
开封第一讲书人阅读 35,146评论 0 106
• 文/不坏的土叔 我叫张陵，是天一观的道长。 经常有香客问我，道长，这世上最难降的妖魔是什么？ 我笑而不...
开封第一讲书人阅读 19,365评论 0 91
• 正文 为了忘掉前任，我火速办了婚礼，结果婚礼上，老公的妹妹穿的比我还像新娘。我一直安慰自己，他们只是感情好，可当我...
茶点故事阅读 24,733评论 0 154
• 文/花漫 我一把揭开白布。 她就那样静静地躺着，像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上，一...
开封第一讲书人阅读 20,515评论 1 91
• 那天，我揣着相机与录音，去河边找鬼。 笑死，一个胖子当着我的面吹牛，可吹牛的内容都是我干的。 我是一名探鬼主播，决...
沈念sama阅读 13,152评论 2 168
• 文/苍兰香墨 我猛地睁开眼，长吁一口气：“原来是场噩梦啊……” “哼！你这毒妇竟也来了？” 一声冷哼从身侧响起，我...
开封第一讲书人阅读 12,545评论 0 84
• 想象着我的养父在大火中拼命挣扎，窒息，最后皮肤化为焦炭。我心中就已经是抑制不住地欢快，这就叫做以其人之道，还治其人...
爱写小说的胖达阅读 11,090评论 5 118
• 序言：老挝万荣一对情侣失踪，失踪者是张志新（化名）和其女友刘颖，没想到半个月后，有当地人在树林里发现了一具尸体，经...
沈念sama阅读 14,380评论 0 132
• 正文 独居荒郊野岭守林人离奇死亡，尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
茶点故事阅读 13,027评论 1 131
• 正文 我和宋清朗相恋三年，在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
茶点故事阅读 13,865评论 0 137
• 白月光回国，霸总把我这个替身辞退。还一脸阴沉的警告我。[不要出现在思思面前， 不然我有一百种方法让你生不如死。]我...
爱写小说的胖达阅读 8,644评论 0 19
• 序言：一个原本活蹦乱跳的男人离奇死亡，死状恐怖，灵堂内的尸体忽然破棺而出，到底是诈尸还是另有隐情，我是刑警宁泽，带...
沈念sama阅读 11,484评论 2 122
• 正文 年R本政府宣布，位于F岛的核电站，受9级特大地震影响，放射性物质发生泄漏。R本人自食恶果不足惜，却给世界环境...
茶点故事阅读 14,664评论 3 132
• 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹，春花似锦、人声如沸。这庄子的主人今日做“春日...
开封第一讲书人阅读 10,223评论 0 3
• 文/苍兰香墨 我抬头看了看天上的太阳。三九已至，却和暖如春，着一层夹袄步出监牢的瞬间，已是汗流浃背。 一阵脚步声响...
开封第一讲书人阅读 10,596评论 0 84
• 我被黑心中介骗来泰国打工， 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留，地道东北人。 一个月前我还...
沈念sama阅读 15,276评论 2 142
• 正文 我出身青楼，却偏偏与公主长得像，于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子，可洞房花烛夜当晚...
茶点故事阅读 15,730评论 2 138