您的位置:首页 > 其它

uva10306(dp)

2014-11-27 21:14 323 查看
就是给你m种硬币 ,和一个目标值s.

每种硬币有两种值,就交x,y把.

现在你要选出几枚硬币,满足 这些硬币的x的和 sumx 和这些硬币的y的和sumy sumx的平方 + sumy的平方 = s的平方.

问最少几枚硬币

首先dp[ i ][ j ] 是代表当左边值的和为 i ,右边值的和为 j 时 ,最少要几枚硬币..

接下去就是背包的思想.假如你现在有两个硬币,x值,y值分别1.3 2 4...

那么你的dp [ i ][ j ] = max(dp[ i - 1][ j - 3] + 1 , dp[i - 2] [j - 4] +1)

为什么呢.因为减掉这枚硬币的值之后,所能达到的最优解 ,在加上这枚硬币(也就是+1),那么就是取这枚硬币达到的最优解.

然后遍历选出满足sumx的平方 + sumy的平方 = s的平方的i,j中值最小的那个.

#include<stdio.h>
#include<string.h>
const int N = 305;
const int INF = 0x3f3f3f3f;
struct coin {
int x ;
int y ;
}c
;
int m,mm ,s;
int dp

;
void solve() {
for(int i = 0 ; i <= s ;i++) {
for (int j = 0 ; j <= s ;j++) {
for (int k = 0 ; k < m ;k++) {
if(i - c[k].x >= 0 && j - c[k].y >= 0)
dp[i][j] = dp[i][j] < dp[i - c[k].x][j - c[k].y] + 1 ?
dp[i][j] : dp[i - c[k].x][j - c[k].y] + 1;
}
}
}
for (int i = 0 ; i <= s ;i++) {
for (int j = 0 ; j <= s ; j++) {
if (i * i + j * j == s * s && dp[i][j] < mm)
mm = dp[i][j];
}
}
}
int main () {
int t;
scanf("%d",&t);
while(t--) {
memset(dp , INF ,sizeof(dp));
dp[0][0] = 0;
scanf("%d%d",&m ,&s);
for (int i = 0 ; i < m ;i++) {
scanf("%d%d",&c[i].x , &c[i].y);
}
mm = INF;
solve();
if(mm == INF)
printf("not possible\n");
else
printf("%d\n",mm);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: