扩展欧几里得+完全背包
87分代码:
#include <stdio.h> #include <memory.h> #include <math.h> #include <string> #include <string.h> #include <vector> #include <set> #include <stack> #include <queue> #include <algorithm> #include <map> #define I scanf #define OL puts #define O printf #define F(a,b,c) for(a=b;a<c;a++) #define FF(a,b) for(a=0;a<b;a++) #define FG(a,b) for(a=b-1;a>=0;a--) #define LEN 3000 #define MAX 0x06FFFFFF #define V vector<int> using namespace std; int a[200]; int dp[10000]; bool judge(int a,int b){ int c; while(b){ c=a%b; a=b; b=c; } // printf("%d\n",a); if(a==1) //存在互质 return true; return false; } int main(){ // freopen("D:/CbWorkspace/blue_bridge/包子凑数.txt","r",stdin); int N,i,j; while(~I("%d",&N)){ FF(i,N){ I("%d",&a[i]); } bool flag=0; FF(i,N){ //如果存在有两个数互质,则有解,不过不存在有两个数互质,无解 FF(j,N){ //隐含步骤:最后让a[n-1]与0进行gcd,a与0的gcd为a if(judge(a[i],a[j])){ flag=1; goto END_JUDGE; } } } END_JUDGE: if(!flag){ puts("INF\n"); continue; } dp[0]=1; FF(i,N){ //物品循环 for(j=0;j+a[i]<10000;j++){ if(dp[j]) //当前可以取到 dp[j+a[i]]=1; //加上当前物品的重量,下一个物品可以取到 //限制条件“j+a[i]<10000 ” 保证了不会溢出 } } int ans=0; FF(i,10000) if(!dp[i]) ans++; printf("%d\n",ans); } return 0; }
AC代码:
#include<stdio.h> #include<string.h> int dp[10000]; bool judge(int x,int y) { int t; while(y>0) { t=x%y; x=y; y=t; } if(x==1) return true; return false; } int main() { int a[200],n,i,j,res,mark; while(scanf("%d",&n)!=EOF) { res=0; mark=0; memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { scanf("%d",&a[i]); } for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(judge(a[i],a[j])) { mark=1; break; } } if(mark==1) break; } if(mark!=1) { printf("INF\n"); continue; } dp[0]=1; for(i=1;i<=n;i++) for(j=1;j<10000;j++) { if(a[i]>j) continue; if(dp[j-a[i]]==1) dp[j]=1; } for(i=0;i<10000;i++) { if(dp[i]!=1) res++; } printf("%d\n",res); } return 0; }