Uva 10306 e-Coins

题意:给定n个物品,每个物品有两个价值,x,y,问能否从中选择一些物品(数量任意),使得sum(x)^2+sum(y)^2==s*s

分析:二维费用的背包,dp[i][j]表示凑出两种费用分别为i,j的最小硬币数

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define N 500
 5 using namespace std;
 6 const int inf=(1<<30);
 7 int dp[N][N];
 8 int w1[N],w2[N];
 9 int main(){
10     int t,m,s;
11     cin>>t;
12     while(t--){
13         cin>>m>>s;
14         for(int i=1;i<=m;i++)
15             cin>>w1[i]>>w2[i];
16             for(int j=0;j<N;j++)
17                 for(int k=0;k<N;k++)
18                     dp[j][k]=inf;
19         dp[0][0]=0;
20         for(int i=1;i<=m;i++)
21             for(int j=w1[i];j<N;j++)
22                 for(int k=w2[i];k<N;k++)
23                     dp[j][k]=min(dp[j][k],dp[j-w1[i]][k-w2[i]]+1);
24         int ans=inf;
25         for(int x=0;x<=s;x++)
26             for(int y=0;y<=s;y++){
27                 if(x*x+y*y!=s*s)continue;
28                 if(dp[x][y]<inf)
29                     ans=min(ans,dp[x][y]);
30                 if(dp[y][x]<inf)
31                     ans=min(ans,dp[y][x]);
32             }
33         if(ans<inf)
34             cout<<ans<<endl;
35         else
36             cout<<"not possible"<<endl;
37     }
38     return 0;
39 }
posted @ 2012-11-02 19:58  silver__bullet  阅读(157)  评论(0编辑  收藏  举报