关于以什么为横纵坐标的问题还是绕了好久。
一开始用的是 dp[经验][忍耐度] = 物品个数 ,转移方程是 dp[i][j] = min(dp[i-exp[kk]][j-lp[kk])+1; 可以从那些已经标记过的或者说从dp[0][0]转移过来。
交了以后WA了,为什么呢......原来经验值可以爆啊。
好吧那么就换。
改用 dp[物品个数][忍耐度] = 经验,转移方程是 dp[i][j] = min(dp[i-1][j-lp[kk]+exp[kk]);
还是WA了,为什么呢......原来忘了memset(跪
AC代码如下:
//21592.cpp
#include <iostream>
#include <cstdio>
using namespace std;
#define maxn 110
#include <cstring>
int exp[maxn],lp[maxn],dp[maxn][maxn];
int main()
{
// freopen("data.txt","r",stdin);
// freopen("21592.out","w",stdout);
int n,m,s,k,i,j,kk,ans;
bool flag;
while (cin >> n >> m >> k >> s)
{
for (i=0;i<k;++i)
cin >> exp[i] >> lp[i];
memset(dp,0,sizeof(dp));
for (i = 1; i <= s; ++ i)
for (j = 1; j<=m;++j)
for (kk=0;kk<k;++kk)
{
if (j-lp[kk]>=0)
dp[i][j] = max(dp[i][j],dp[i-1][j-lp[kk]]+exp[kk]);
}
flag = false;
ans = 0;
for (i=1;i<=s;++i)
{
for (j=1;j<=m;++j)
{
if (dp[i][j]>=n)
{
flag = true;
ans = max(m-j,ans);
break;
}
}
}
if (flag)
cout << ans << endl;
else
cout << "-1" << endl;
}
// fclose(stdin);
// fclose(stdout);
}