POI2006EST-Aesthetic Text

POI #Year2006 #dp

\(dp_{i,j}\) 表示考虑到第 \(i\) 个单词,当前行长度为 \(j\) 的最小代价

暴力转移是 \(\mathcal{O}(n^3)\)

然后观察到,其实合法的转移不能卡满,具体来说,有至少 \(\frac{1}{16}\) 的常数,因为 \(dp\) 转移还有 \(<1\) 的常数,所以可以水过去

// Author: xiaruize
int max(int a, int b)
{
	if (a > b)
		return a;
	return b;
}
int min(int a, int b)
{
	if (a < b)
		return a;
	return b;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 2e3 + 10;

int n, m;
int a[N], dp[N][N], sum[N];
int res = INF;

void solve()
{
	cin >> m >> n;
	rep(i, 1, n)
	{
		cin >> a[i];
		sum[i] = sum[i - 1] + a[i] + 1;
	}
	mms(dp, 0x3f);
	rep(i, 1, n)
	{
		if (sum[i] > m + 1)
			break;
		dp[i][0] = 0;
	}
	rep(i, 1, n)
	{
		rep(j, 0, i - 1)
		{
			if (sum[i] - sum[j] <= m + 1)
			{
				rep(k, 0, j - 1)
					dp[i][j] = min(dp[i][j], dp[j][k] + abs(sum[i] - 2 * sum[j] + sum[k]));
			}
			else
				dp[i][j] = dp[0][0];
		}
	}
	rep(i, 0, n - 1) res = min(res, dp[n][i]);
	cout << res << endl;
}

#ifndef ONLINE_JUDGE
bool end_of_memory_use;
#endif

signed main()
{
	// freopen(".in","r",stdin);
	// freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int testcase = 1;
	// cin >> testcase;
	while (testcase--)
		solve();
#ifndef ONLINE_JUDGE
	cerr << "Memory use:" << (&end_of_memory_use - &start_of_memory_use) / 1024.0 / 1024.0 << "MiB" << endl;
	cerr << "Time use:" << (double)clock() / CLOCKS_PER_SEC * 1000.0 << "ms" << endl;
#endif
	return 0;
}
posted @ 2024-04-15 19:41  xiaruize  阅读(15)  评论(0)    收藏  举报