您的位置:首页 > 其它

TOJ 4620

2014-03-16 21:36 197 查看
题目标题:

A Story on a Sunshine Beach

题目连接:
http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=4620
题目类型:

动态规划 - 01背包+记录

数据结构:

int g[105][1005] = { 0 }, //记录方案
dp[105][1005] = { 0 };
思路分析:

单纯的01背包问题

只不过在输出的时候多了两个条件

一个是输出方案

多申请一组数组来保存方案 

等待全部记录完成后 在终点dp(n,m)往回推即可

另一个条件是 方案数需要根据字典序最小的输出

也就是说 可能存在多种合理的方案

要输出字典序最小的方案

这点可以吧输入和推理背包的顺序颠倒过来

先从第N个背包开始依次处理到第1个背包

输出方案的时候也要遵循这个规则

证明:



源代码:

#include <stdio.h>
#include <iostream>

using namespace std;

struct LMIC_STONE
{
int w, s;

}arr[105];

int n;

int main()
{
//freopen( "E:\\in.txt", "r", stdin );

int i, j, n, m, t;

scanf( "%d", &t );

while( t -- )
{
int g[105][1005] = { 0 }, //记录方案
dp[105][1005] = { 0 };

scanf( "%d%d", &n, &m );

for( i = 1; i <= n; i ++ )
{
scanf( "%d%d", &arr[i].w , &arr[i].s );
}

for( i = n; i >= 1; i -- )
{
for( j = 0; j <= m ; j ++ )
{
if( j - arr[i].w < 0 )
{
dp[i][j] = dp[i + 1][j];
g[i][j] = 0;
continue;
}

if( dp[i + 1][j] > dp[i + 1][j - arr[i].w] + arr[i].s )
{
dp[i][j] = dp[i + 1][j];
g[i][j] = 0;
}
else
{
dp[i][j] = dp[i + 1][j - arr[i].w] + arr[i].s;
g[i][j] = 1;
}
}
}

printf( "%d\n", dp[1][m] );

bool fir = false;

for( i = 1, j = m; i <= n; i ++ )
{
if( g[i][j] )
{
if( fir )
{
printf( " " );
}

printf( "%d", i );
j = j - arr[i].w;

fir = true;
}
}

printf( "\n" );
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划